OEMCrypto v18.3
Updates to OEMCrypto API, OPK, ODK, and unit tests. See the file CHANGELOG.md for details.
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
#ifndef ERROR_STRING_UTIL_H_
|
||||
#define ERROR_STRING_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace wvutil {
|
||||
|
||||
const std::string OEMCryptoResultToString(int oemcrypto_result);
|
||||
|
||||
} // namespace wvutil
|
||||
#endif // ERROR_STRING_UTIL_H_
|
||||
@@ -58,6 +58,7 @@ class FileSystem {
|
||||
virtual std::unique_ptr<File> Open(const std::string& file_path, int flags);
|
||||
|
||||
virtual bool Exists(const std::string& file_path);
|
||||
virtual bool Exists(const std::string& file_path, int* errno_value);
|
||||
virtual bool Remove(const std::string& file_path);
|
||||
virtual ssize_t FileSize(const std::string& file_path);
|
||||
|
||||
|
||||
@@ -13,6 +13,11 @@ namespace wvutil {
|
||||
#endif
|
||||
bool FormatString(std::string* out, const char* fmt, ...);
|
||||
|
||||
#ifdef __GNUC__
|
||||
[[gnu::format(printf, 2, 0)]]
|
||||
#endif
|
||||
bool VFormatString(std::string* out, const char* fmt, va_list vlist);
|
||||
|
||||
} // namespace wvutil
|
||||
|
||||
#endif // WVCDM_UTIL_STRING_FORMAT_H_
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
|
||||
#include "error_string_util.h"
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvutil {
|
||||
const std::string OEMCryptoResultToString(int oemcrypto_result) {
|
||||
switch (oemcrypto_result) {
|
||||
case OEMCrypto_SUCCESS:
|
||||
return "SUCCESS";
|
||||
case OEMCrypto_ERROR_INIT_FAILED:
|
||||
return "INIT_FAILED";
|
||||
case OEMCrypto_ERROR_TERMINATE_FAILED:
|
||||
return "TERMINATE_FAILED";
|
||||
case OEMCrypto_ERROR_OPEN_FAILURE:
|
||||
return "OPEN_FAILURE";
|
||||
case OEMCrypto_ERROR_CLOSE_FAILURE:
|
||||
return "CLOSE_FAILURE";
|
||||
case OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED:
|
||||
return "ENTER_SECURE_PLAYBACK_FAILED";
|
||||
case OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED:
|
||||
return "EXIT_SECURE_PLAYBACK_FAILED";
|
||||
case OEMCrypto_ERROR_SHORT_BUFFER:
|
||||
return "SHORT_BUFFER";
|
||||
case OEMCrypto_ERROR_NO_DEVICE_KEY:
|
||||
return "NO_DEVICE_KEY";
|
||||
case OEMCrypto_ERROR_NO_ASSET_KEY:
|
||||
return "NO_ASSET_KEY";
|
||||
case OEMCrypto_ERROR_KEYBOX_INVALID:
|
||||
return "KEYBOX_INVALID";
|
||||
case OEMCrypto_ERROR_NO_KEYDATA:
|
||||
return "NO_KEYDATA";
|
||||
case OEMCrypto_ERROR_NO_CW:
|
||||
return "NO_CW";
|
||||
case OEMCrypto_ERROR_DECRYPT_FAILED:
|
||||
return "DECRYPT_FAILED";
|
||||
case OEMCrypto_ERROR_WRITE_KEYBOX:
|
||||
return "WRITE_KEYBOX";
|
||||
case OEMCrypto_ERROR_WRAP_KEYBOX:
|
||||
return "WRAP_KEYBOX";
|
||||
case OEMCrypto_ERROR_BAD_MAGIC:
|
||||
return "BAD_MAGIC";
|
||||
case OEMCrypto_ERROR_BAD_CRC:
|
||||
return "BAD_CRC";
|
||||
case OEMCrypto_ERROR_NO_DEVICEID:
|
||||
return "NO_DEVICEID";
|
||||
case OEMCrypto_ERROR_RNG_FAILED:
|
||||
return "RNG_FAILED";
|
||||
case OEMCrypto_ERROR_RNG_NOT_SUPPORTED:
|
||||
return "RNG_NOT_SUPPORTED";
|
||||
case OEMCrypto_ERROR_SETUP:
|
||||
return "SETUP";
|
||||
case OEMCrypto_ERROR_OPEN_SESSION_FAILED:
|
||||
return "OPEN_SESSION_FAILED";
|
||||
case OEMCrypto_ERROR_CLOSE_SESSION_FAILED:
|
||||
return "CLOSE_SESSION_FAILED";
|
||||
case OEMCrypto_ERROR_INVALID_SESSION:
|
||||
return "INVALID_SESSION";
|
||||
case OEMCrypto_ERROR_NOT_IMPLEMENTED:
|
||||
return "NOT_IMPLEMENTED";
|
||||
case OEMCrypto_ERROR_NO_CONTENT_KEY:
|
||||
return "NO_CONTENT_KEY";
|
||||
case OEMCrypto_ERROR_CONTROL_INVALID:
|
||||
return "CONTROL_INVALID";
|
||||
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
|
||||
return "UNKNOWN_FAILURE";
|
||||
case OEMCrypto_ERROR_INVALID_CONTEXT:
|
||||
return "INVALID_CONTEXT";
|
||||
case OEMCrypto_ERROR_SIGNATURE_FAILURE:
|
||||
return "SIGNATURE_FAILURE";
|
||||
case OEMCrypto_ERROR_TOO_MANY_SESSIONS:
|
||||
return "TOO_MANY_SESSIONS";
|
||||
case OEMCrypto_ERROR_INVALID_NONCE:
|
||||
return "INVALID_NONCE";
|
||||
case OEMCrypto_ERROR_TOO_MANY_KEYS:
|
||||
return "TOO_MANY_KEYS";
|
||||
case OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED:
|
||||
return "DEVICE_NOT_RSA_PROVISIONED";
|
||||
case OEMCrypto_ERROR_INVALID_RSA_KEY:
|
||||
return "INVALID_RSA_KEY";
|
||||
case OEMCrypto_ERROR_KEY_EXPIRED:
|
||||
return "KEY_EXPIRED";
|
||||
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
|
||||
return "INSUFFICIENT_RESOURCES";
|
||||
case OEMCrypto_ERROR_INSUFFICIENT_HDCP:
|
||||
return "INSUFFICIENT_HDCP";
|
||||
case OEMCrypto_ERROR_BUFFER_TOO_LARGE:
|
||||
return "BUFFER_TOO_LARGE";
|
||||
case OEMCrypto_WARNING_GENERATION_SKEW:
|
||||
return "OEMCrypto_WARNING_GENERATION_SKEW";
|
||||
case OEMCrypto_ERROR_GENERATION_SKEW:
|
||||
return "GENERATION_SKEW";
|
||||
case OEMCrypto_LOCAL_DISPLAY_ONLY:
|
||||
return "OEMCrypto_LOCAL_DISPLAY_ONLY";
|
||||
case OEMCrypto_ERROR_ANALOG_OUTPUT:
|
||||
return "ANALOG_OUTPUT";
|
||||
case OEMCrypto_ERROR_WRONG_PST:
|
||||
return "WRONG_PST";
|
||||
case OEMCrypto_ERROR_WRONG_KEYS:
|
||||
return "WRONG_KEYS";
|
||||
case OEMCrypto_ERROR_MISSING_MASTER:
|
||||
return "MISSING_MASTER";
|
||||
case OEMCrypto_ERROR_LICENSE_INACTIVE:
|
||||
return "LICENSE_INACTIVE";
|
||||
case OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE:
|
||||
return "ENTRY_NEEDS_UPDATE";
|
||||
case OEMCrypto_ERROR_ENTRY_IN_USE:
|
||||
return "ENTRY_IN_USE";
|
||||
case OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE:
|
||||
return "USAGE_TABLE_UNRECOVERABLE";
|
||||
case OEMCrypto_KEY_NOT_LOADED:
|
||||
return "OEMCrypto_KEY_NOT_LOADED";
|
||||
case OEMCrypto_KEY_NOT_ENTITLED:
|
||||
return "OEMCrypto_KEY_NOT_ENTITLED";
|
||||
case OEMCrypto_ERROR_BAD_HASH:
|
||||
return "BAD_HASH";
|
||||
case OEMCrypto_ERROR_OUTPUT_TOO_LARGE:
|
||||
return "OUTPUT_TOO_LARGE";
|
||||
case OEMCrypto_ERROR_SESSION_LOST_STATE:
|
||||
return "SESSION_LOST_STATE";
|
||||
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
|
||||
return "SYSTEM_INVALIDATED";
|
||||
case OEMCrypto_ERROR_LICENSE_RELOAD:
|
||||
return "LICENSE_RELOAD";
|
||||
case OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES:
|
||||
return "MULTIPLE_USAGE_ENTRIES";
|
||||
case OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION:
|
||||
return "MIXED_OUTPUT_PROTECTION";
|
||||
case OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION:
|
||||
return "INVALID_ENTITLED_KEY_SESSION";
|
||||
case OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING:
|
||||
return "NEEDS_KEYBOX_PROVISIONING";
|
||||
case OEMCrypto_ERROR_UNSUPPORTED_CIPHER:
|
||||
return "OEMCrypto_ERROR_UNSUPPORTED_CIPHER";
|
||||
case OEMCrypto_ERROR_DVR_FORBIDDEN:
|
||||
return "OEMCrypto_ERROR_DVR_FORBIDDEN";
|
||||
case OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE:
|
||||
return "OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE";
|
||||
case OEMCrypto_ERROR_INVALID_KEY:
|
||||
return "INVALID_KEY";
|
||||
// ODK Values.
|
||||
case ODK_ERROR_CORE_MESSAGE:
|
||||
return "CORE_MESSAGE";
|
||||
case ODK_SET_TIMER:
|
||||
return "SET_TIMER";
|
||||
case ODK_DISABLE_TIMER:
|
||||
return "DISABLE_TIMER";
|
||||
case ODK_TIMER_EXPIRED:
|
||||
return "TIMER_EXPIRED";
|
||||
case ODK_UNSUPPORTED_API:
|
||||
return "UNSUPPORTED_API";
|
||||
case ODK_STALE_RENEWAL:
|
||||
return "STALE_RENEWAL";
|
||||
// OPK Values.
|
||||
case OPK_ERROR_INCOMPATIBLE_VERSION:
|
||||
return "INCOMPATIBLE_VERSION";
|
||||
case OPK_ERROR_REMOTE_CALL:
|
||||
return "REMOTE_CALL";
|
||||
case OPK_ERROR_NO_PERSISTENT_DATA:
|
||||
return "NO_PERSISTENT_DATA";
|
||||
default:
|
||||
return "Invalid OEMCrypto error.";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wvutil
|
||||
@@ -16,20 +16,27 @@ namespace wvutil {
|
||||
bool FormatString(std::string* out, const char* fmt, ...) {
|
||||
if (out == nullptr || fmt == nullptr) return false;
|
||||
|
||||
va_list ap1;
|
||||
va_start(ap1, fmt);
|
||||
const int desired_size = vsnprintf(nullptr, 0, fmt, ap1);
|
||||
va_end(ap1);
|
||||
va_list vlist;
|
||||
va_start(vlist, fmt);
|
||||
const bool result = VFormatString(out, fmt, vlist);
|
||||
va_end(vlist);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool VFormatString(std::string* out, const char* fmt, va_list vlist) {
|
||||
if (out == nullptr || fmt == nullptr) return false;
|
||||
|
||||
va_list vlist_copy;
|
||||
va_copy(vlist_copy, vlist);
|
||||
const int desired_size = vsnprintf(nullptr, 0, fmt, vlist_copy);
|
||||
va_end(vlist_copy);
|
||||
|
||||
if (desired_size < 0) return false;
|
||||
const size_t buffer_size =
|
||||
static_cast<size_t>(desired_size) + 1; // +1 for null
|
||||
std::unique_ptr<char[]> buffer(new char[buffer_size]);
|
||||
|
||||
va_list ap2;
|
||||
va_start(ap2, fmt);
|
||||
const int actual_size = vsnprintf(buffer.get(), buffer_size, fmt, ap2);
|
||||
va_end(ap2);
|
||||
const int actual_size = vsnprintf(buffer.get(), buffer_size, fmt, vlist);
|
||||
|
||||
if (actual_size != desired_size) return false;
|
||||
|
||||
|
||||
@@ -39,9 +39,17 @@ class FileTest : public testing::Test {
|
||||
};
|
||||
|
||||
TEST_F(FileTest, FileExists) {
|
||||
int errno_value = -1;
|
||||
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kExistentFile));
|
||||
EXPECT_TRUE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kExistentFile, &errno_value));
|
||||
EXPECT_EQ(0, errno_value);
|
||||
EXPECT_TRUE(file_system_.Exists(wvcdm::test_vectors::kExistentDir));
|
||||
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kNonExistentFile));
|
||||
EXPECT_FALSE(
|
||||
file_system_.Exists(wvcdm::test_vectors::kNonExistentFile, &errno_value));
|
||||
EXPECT_EQ(ENOENT, errno_value);
|
||||
EXPECT_FALSE(file_system_.Exists(wvcdm::test_vectors::kNonExistentDir));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -53,6 +54,18 @@ void TestSleep::Sleep(unsigned int seconds) {
|
||||
if (callback_ != nullptr) callback_->ElapseTime(milliseconds);
|
||||
}
|
||||
|
||||
void TestSleep::SleepUntil(int64_t desired_time) {
|
||||
SyncFakeClock();
|
||||
const int64_t now = Clock().GetCurrentTime();
|
||||
if (desired_time < now) {
|
||||
LOGE("Test Clock skew sleeping from time %" PRId64 " to %" PRId64, now,
|
||||
desired_time);
|
||||
return;
|
||||
}
|
||||
const unsigned int sleep_time = static_cast<unsigned int>(desired_time - now);
|
||||
TestSleep::Sleep(sleep_time);
|
||||
}
|
||||
|
||||
void TestSleep::SyncFakeClock() {
|
||||
// Syncing can be done by sleeping 0 seconds.
|
||||
Sleep(0);
|
||||
|
||||
@@ -13,7 +13,9 @@ namespace wvutil {
|
||||
|
||||
class TestSleep {
|
||||
public:
|
||||
// The callback is called when the clock should be advanced.
|
||||
// The callback is called when the test clock should be advanced. If the
|
||||
// system uses a real clock, it is used to sync the real and test
|
||||
// clock. Otherwise it is used to simulate sleep in the test clock.
|
||||
class CallBack {
|
||||
public:
|
||||
virtual void ElapseTime(int64_t milliseconds) = 0;
|
||||
@@ -27,6 +29,9 @@ class TestSleep {
|
||||
// callback exists, this calls the callback.
|
||||
static void Sleep(unsigned int seconds);
|
||||
|
||||
// Like sleep, above, except it sleeps until the specified time.
|
||||
static void SleepUntil(int64_t desired_time);
|
||||
|
||||
// If we are using a real clock and a fake clock, then the real clock advances
|
||||
// a little while we are doing work, but the fake one only advances when we
|
||||
// sleep. This function advances the fake clock to be in sync with the real
|
||||
|
||||
Reference in New Issue
Block a user