Update TimeRollbackPrevention unit test

Merge from Widevine repo of http://go/wvgerrit/100110

The unit test TimeRollbackPrevention was broken for several
reasons. This CL reduces the test to its most basic functionality and
updates it to be compatible with a v16 oemcrypto.

This CL also adjusts the fake clock used by the buildbot to fake
sleeping backwards, so that the TimeRollbackPrevention test can also
be run on the buildbot.

Bug: 155773482
Bug: 79422351
Test: unit tests on buildbot, and on flame w/v16 modmock
Change-Id: I3027018b17b738281989e63ae6b0729757217d05
This commit is contained in:
Fred Gylys-Colwell
2020-05-15 14:13:20 -07:00
parent 760bf71908
commit 75575418d0
6 changed files with 240 additions and 205 deletions

View File

@@ -102,6 +102,7 @@ int64_t CryptoEngine::MonotonicTime() {
wvcdm::Clock().GetCurrentTime() + offline_time_info_.rollback_offset;
static int64_t then = now;
if (now < then) {
LOGW("Clock rollback detected: %lld seconds", then - now);
offline_time_info_.rollback_offset += then - now;
now = then;
}
@@ -138,31 +139,16 @@ bool CryptoEngine::LoadOfflineTimeInfo(const std::string& file_path) {
memset(&offline_time_info_, 0, sizeof(TimeInfo));
wvcdm::FileSystem* file_system = file_system_.get();
if (file_system->Exists(file_path)) {
std::vector<uint8_t> encrypted_buffer(sizeof(TimeInfo));
std::vector<uint8_t> clear_buffer(sizeof(TimeInfo));
KeyboxError error_code = ValidateKeybox();
if (error_code != NO_ERROR) {
LOGE("Keybox is invalid: %d", error_code);
return false;
}
// Use the device key for encrypt/decrypt.
const std::vector<uint8_t>& key = DeviceRootKey();
std::unique_ptr<wvcdm::File> file =
file_system->Open(file_path, wvcdm::FileSystem::kReadOnly);
if (!file) {
LOGE("File open failed: %s", file_path.c_str());
// This error is expected at first initialization.
LOGE("File open failed (this is expected on first initialization): %s",
file_path.c_str());
return false;
}
// Load time info from previous call.
file->Read(reinterpret_cast<char*>(&encrypted_buffer[0]), sizeof(TimeInfo));
// Decrypt the encrypted TimeInfo buffer.
AES_KEY aes_key;
AES_set_decrypt_key(&key[0], 128, &aes_key);
std::vector<uint8_t> iv(wvoec::KEY_IV_SIZE, 0);
AES_cbc_encrypt(&encrypted_buffer[0], &clear_buffer[0], sizeof(TimeInfo),
&aes_key, iv.data(), AES_DECRYPT);
memcpy(&offline_time_info_, &clear_buffer[0], sizeof(TimeInfo));
file->Read(reinterpret_cast<char*>(&offline_time_info_), sizeof(TimeInfo));
// Detect offline time rollback after loading from disk.
// Add any time offsets in the past to the current time.
@@ -191,34 +177,16 @@ bool CryptoEngine::SaveOfflineTimeInfo(const std::string& file_path) {
if (current_time > offline_time_info_.previous_time)
offline_time_info_.previous_time = current_time;
KeyboxError error_code = ValidateKeybox();
if (error_code != NO_ERROR) {
LOGE("Keybox is invalid: %d", error_code);
return false;
}
// Use the device key for encrypt/decrypt.
const std::vector<uint8_t>& key = DeviceRootKey();
std::vector<uint8_t> encrypted_buffer(sizeof(TimeInfo));
std::vector<uint8_t> clear_buffer(sizeof(TimeInfo));
// Copy updated data and encrypt the buffer.
memcpy(&clear_buffer[0], &offline_time_info_, sizeof(TimeInfo));
AES_KEY aes_key;
AES_set_encrypt_key(&key[0], 128, &aes_key);
std::vector<uint8_t> iv(wvoec::KEY_IV_SIZE, 0);
AES_cbc_encrypt(&clear_buffer[0], &encrypted_buffer[0], sizeof(TimeInfo),
&aes_key, iv.data(), AES_ENCRYPT);
std::unique_ptr<wvcdm::File> file;
wvcdm::FileSystem* file_system = file_system_.get();
// Write the encrypted buffer to disk.
// Write the current time and offset to disk.
file = file_system->Open(
file_path, wvcdm::FileSystem::kCreate | wvcdm::FileSystem::kTruncate);
if (!file) {
LOGE("File open failed: %s", file_path.c_str());
return false;
}
file->Write(reinterpret_cast<char*>(&encrypted_buffer[0]), sizeof(TimeInfo));
file->Write(reinterpret_cast<char*>(&offline_time_info_), sizeof(TimeInfo));
return true;
}