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:
Fred Gylys-Colwell
2017-05-02 13:54:02 -07:00
parent 6262f3721f
commit 38b5e8c71c
9 changed files with 50 additions and 28 deletions

View File

@@ -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),