Refresh Current Key in Level 3
Merge from Widevine repo of http://go/wvgerrit/26780 and http://go/wvgerrit/26740 Previously, in oemcrypto level 3, a session's current key's duration was not updated until the next call to SelectKey. This caused problems with license that only used one key. This CL fixes that. arm64/libwvlevel3.a Level3 Library 7283 May 2 2017 13:16:21 arm/libwvlevel3.a Level3 Library 4445 May 2 2017 11:49:34 x86_64/libwvlevel3.a Level3 Library 7284 May 2 2017 12:09:21 x86/libwvlevel3.a Level3 Library 4464 May 2 2017 11:53:46 Test: unit tests run on emulator. b/37481239 b/37523523 Change-Id: Ife90a3358b6620c8fb81324ec2331d3775a38191
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -5,8 +5,6 @@ LOCAL_MODULE_CLASS := STATIC_LIBRARIES
|
||||
LOCAL_MODULE_SUFFIX := .a
|
||||
LOCAL_SRC_FILES := level3_stubs.cpp
|
||||
|
||||
LOCAL_CFLAGS := -Wno-unused-parameter
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
@@ -16,5 +14,5 @@ LOCAL_C_INCLUDES := \
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_OWNER := widevine
|
||||
LOCAL_MODULE_TARGET_ARCH := mips
|
||||
LOCAL_MODULE_TARGET_ARCH := mips mips64
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
@@ -279,6 +279,12 @@ OEMCryptoResult Level3_UpdateUsageTable() {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OEMCryptoResult Level3_DeactivateUsageEntry(OEMCrypto_SESSION session,
|
||||
const uint8_t *pst,
|
||||
size_t pst_length) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OEMCryptoResult Level3_ReportUsage(OEMCrypto_SESSION session,
|
||||
const uint8_t *pst,
|
||||
size_t pst_length,
|
||||
@@ -379,19 +385,5 @@ OEMCryptoResult Level3_CreateOldUsageEntry(uint64_t time_since_license_received,
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
uint32_t Level3_SupportedCertificates() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OEMCryptoResult Level3_GetOEMPublicCertificate(OEMCrypto_SESSION session,
|
||||
uint8_t *public_cert,
|
||||
size_t *public_cert_length) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
OEMCrypto_ProvisioningMethod Level3_GetProvisioningMethod() {
|
||||
return OEMCrypto_ProvisioningError;
|
||||
}
|
||||
|
||||
|
||||
} // namespace wvoec3
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libwvlevel3
|
||||
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
|
||||
LOCAL_MODULE_SUFFIX := .a
|
||||
LOCAL_SRC_FILES := $(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX)
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_OWNER := widevine
|
||||
LOCAL_MODULE_TARGET_ARCH := mips64
|
||||
include $(BUILD_PREBUILT)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1526,6 +1526,49 @@ TEST_P(SessionTestRefreshKeyTest, RefreshLargeBuffer) {
|
||||
s.get_nonce(), OEMCrypto_SUCCESS));
|
||||
}
|
||||
|
||||
// This situation would occur if an app only uses one key in the license. When
|
||||
// that happens, SelectKey would be called before the first decrypt, and then
|
||||
// would not need to be called again, even if the license is refreshed.
|
||||
TEST_P(SessionTestRefreshKeyTest, RefreshWithNoSelectKey) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
|
||||
// Call select key before the refresh. No calls below to TestDecryptCTR with
|
||||
// select key set to true.
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(true));
|
||||
|
||||
s.GenerateNonce();
|
||||
// License renewal message is signed by client and verified by the server.
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
|
||||
// Note: we store the message in encrypted_license_, but the refresh key
|
||||
// message is not actually encrypted. It is, however, signed.
|
||||
// FillRefreshMessage fills the message with a duration of kLongDuration.
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillRefreshMessage(
|
||||
num_keys_, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
|
||||
s.ServerSignBuffer(reinterpret_cast<const uint8_t*>(&s.encrypted_license()),
|
||||
s.message_size(), &s.signature());
|
||||
OEMCrypto_KeyRefreshObject key_array[num_keys_];
|
||||
s.FillRefreshArray(key_array, num_keys_);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
OEMCrypto_RefreshKeys(s.session_id(), s.message_ptr(),
|
||||
s.message_size(), &s.signature()[0],
|
||||
s.signature().size(), num_keys_, key_array));
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(false));
|
||||
// This should still be valid key, even if the refresh failed, because this
|
||||
// is before the original license duration.
|
||||
sleep(kShortSleep);
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(false));
|
||||
// This should be after duration of the original license, but before the
|
||||
// expiration of the refresh message. This should succeed if and only if the
|
||||
// refresh succeeded.
|
||||
sleep(kShortSleep + kLongSleep);
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(false));
|
||||
}
|
||||
|
||||
// Of only one key control block in the refesh, we update all the keys.
|
||||
INSTANTIATE_TEST_CASE_P(TestRefreshAllKeys, SessionTestRefreshKeyTest,
|
||||
Values(std::make_pair(true, 1),
|
||||
|
||||
Reference in New Issue
Block a user