Version 18.1

Updates to OEMCrypto API, OPK, ODK, and unit tests.

See the file CHANGELOG.md for details.
This commit is contained in:
Fred Gylys-Colwell
2023-03-08 22:05:11 -08:00
committed by John "Juce" Bruce
parent 5232c51e33
commit 562f64f292
499 changed files with 29039 additions and 15184 deletions

View File

@@ -0,0 +1,11 @@
#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_

View File

@@ -28,7 +28,7 @@ static const std::string kOemCertificateFileName = "oemcert.bin";
static const std::string kOemCertificateFileNamePrefix = "oemcert_";
// File class. The implementation is platform dependent.
class CORE_UTIL_EXPORT File {
class File {
public:
File() {}
virtual ~File() {}
@@ -39,7 +39,7 @@ class CORE_UTIL_EXPORT File {
CORE_DISALLOW_COPY_AND_ASSIGN(File);
};
class CORE_UTIL_EXPORT FileSystem {
class FileSystem {
public:
FileSystem();
FileSystem(const std::string& origin, void* extra_data);

View File

@@ -77,31 +77,34 @@ struct LoggingUidSetter {
// This function is supplied for cases where the system layer does not
// initialize logging. This is also needed to initialize logging in
// unit tests.
CORE_UTIL_EXPORT void InitLogging();
void InitLogging();
#ifdef __GNUC__
[[gnu::format(printf, 5, 6)]] CORE_UTIL_EXPORT void Log(const char* file,
const char* function,
int line,
LogPriority level,
const char* fmt, ...);
#else
CORE_UTIL_EXPORT void Log(const char* file, const char* function, int line,
LogPriority level, const char* fmt, ...);
[[gnu::format(printf, 5, 6)]]
#endif
void Log(const char* file, const char* function, int line,
LogPriority level, const char* fmt, ...);
// Log APIs
#ifndef LOGE
# define LOGE(...) \
#ifdef CDM_DISABLE_LOGGING
# define LOGE(...) (void)0
# define LOGW(...) (void)0
# define LOGI(...) (void)0
# define LOGD(...) (void)0
# define LOGV(...) (void)0
#else
# ifndef LOGE
# define LOGE(...) \
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_ERROR, __VA_ARGS__)
# define LOGW(...) \
# define LOGW(...) \
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_WARN, __VA_ARGS__)
# define LOGI(...) \
# define LOGI(...) \
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_INFO, __VA_ARGS__)
# define LOGD(...) \
# define LOGD(...) \
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_DEBUG, __VA_ARGS__)
# define LOGV(...) \
# define LOGV(...) \
Log(__FILE__, __func__, __LINE__, wvutil::CDM_LOG_VERBOSE, __VA_ARGS__)
# endif
#endif
} // namespace wvutil

View File

@@ -21,7 +21,7 @@
using ssize_t = SSIZE_T;
inline void sleep(int seconds) { Sleep(seconds * 1000); }
CORE_UTIL_EXPORT int setenv(const char* key, const char* value, int overwrite);
int setenv(const char* key, const char* value, int overwrite);
#else
# include <arpa/inet.h>
# include <sys/types.h>

View File

@@ -16,7 +16,7 @@
namespace wvutil {
// A simple reader-writer mutex implementation that mimics the one from C++17
class CORE_UTIL_EXPORT shared_mutex {
class shared_mutex {
public:
shared_mutex() : reader_count_(0), has_writer_(false) {}
~shared_mutex();

View File

@@ -15,53 +15,46 @@
namespace wvutil {
// ASCII hex to Binary conversion.
CORE_UTIL_EXPORT std::vector<uint8_t> a2b_hex(const std::string& b);
CORE_UTIL_EXPORT std::vector<uint8_t> a2b_hex(const std::string& label,
const std::string& b);
CORE_UTIL_EXPORT std::string a2bs_hex(const std::string& b);
std::vector<uint8_t> a2b_hex(const std::string& b);
std::vector<uint8_t> a2b_hex(const std::string& label,
const std::string& b);
std::string a2bs_hex(const std::string& b);
// Binary to ASCII hex conversion. The default versions limit output to 2k to
// protect us from log spam. The unlimited version has no length limit.
CORE_UTIL_EXPORT std::string b2a_hex(const std::vector<uint8_t>& b);
CORE_UTIL_EXPORT std::string unlimited_b2a_hex(const std::vector<uint8_t>& b);
CORE_UTIL_EXPORT std::string b2a_hex(const std::string& b);
CORE_UTIL_EXPORT std::string unlimited_b2a_hex(const std::string& b);
CORE_UTIL_EXPORT std::string HexEncode(const uint8_t* bytes, size_t size);
CORE_UTIL_EXPORT std::string UnlimitedHexEncode(const uint8_t* bytes,
size_t size);
std::string b2a_hex(const std::vector<uint8_t>& b);
std::string unlimited_b2a_hex(const std::vector<uint8_t>& b);
std::string b2a_hex(const std::string& b);
std::string unlimited_b2a_hex(const std::string& b);
std::string HexEncode(const uint8_t* bytes, size_t size);
std::string UnlimitedHexEncode(const uint8_t* bytes, size_t size);
// Base64 encoding/decoding.
// Converts binary data into the ASCII Base64 character set and vice
// versa using the encoding rules defined in RFC4648 section 4.
CORE_UTIL_EXPORT std::string Base64Encode(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::string Base64Encode(const std::string& bin_input);
CORE_UTIL_EXPORT std::vector<uint8_t> Base64Decode(
const std::string& bin_input);
std::string Base64Encode(const std::vector<uint8_t>& bin_input);
std::string Base64Encode(const std::string& bin_input);
std::vector<uint8_t> Base64Decode(const std::string& bin_input);
// URL-Safe Base64 encoding/decoding.
// Converts binary data into the URL/Filename safe ASCII Base64
// character set and vice versa using the encoding rules defined in
// RFC4648 section 5.
CORE_UTIL_EXPORT std::string Base64SafeEncode(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::string Base64SafeEncode(const std::string& bin_input);
CORE_UTIL_EXPORT std::vector<uint8_t> Base64SafeDecode(
const std::string& bin_input);
std::string Base64SafeEncode(const std::vector<uint8_t>& bin_input);
std::string Base64SafeEncode(const std::string& bin_input);
std::vector<uint8_t> Base64SafeDecode(const std::string& bin_input);
// URL-Safe Base64 encoding without padding.
// Similar to Base64SafeEncode(), without any padding character '='
// at the end.
CORE_UTIL_EXPORT std::string Base64SafeEncodeNoPad(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::string Base64SafeEncodeNoPad(
const std::string& bin_input);
std::string Base64SafeEncodeNoPad(const std::vector<uint8_t>& bin_input);
std::string Base64SafeEncodeNoPad(const std::string& bin_input);
// Host to Network/Network to Host conversion.
CORE_UTIL_EXPORT int64_t htonll64(int64_t x);
CORE_UTIL_EXPORT inline int64_t ntohll64(int64_t x) { return htonll64(x); }
int64_t htonll64(int64_t x);
inline int64_t ntohll64(int64_t x) { return htonll64(x); }
// Encode unsigned integer into a big endian formatted string.
CORE_UTIL_EXPORT std::string EncodeUint32(uint32_t u);
std::string EncodeUint32(uint32_t u);
} // namespace wvutil

View File

@@ -0,0 +1,18 @@
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
#ifndef WVCDM_UTIL_STRING_FORMAT_H_
#define WVCDM_UTIL_STRING_FORMAT_H_
#include <string>
namespace wvutil {
#ifdef __GNUC__
[[gnu::format(printf, 2, 3)]]
#endif
bool FormatString(std::string* out, const char* fmt, ...);
} // namespace wvutil
#endif // WVCDM_UTIL_STRING_FORMAT_H_

View File

@@ -9,23 +9,11 @@
#ifdef _WIN32
# ifdef CORE_UTIL_IMPLEMENTATION
# define CORE_UTIL_EXPORT __declspec(dllexport)
# else
# define CORE_UTIL_EXPORT __declspec(dllimport)
# endif
# define CORE_UTIL_IGNORE_DEPRECATED
# define CORE_UTIL_RESTORE_WARNINGS
#else
# ifdef CORE_UTIL_IMPLEMENTATION
# define CORE_UTIL_EXPORT __attribute__((visibility("default")))
# else
# define CORE_UTIL_EXPORT
# endif
# ifdef __GNUC__
# define CORE_UTIL_IGNORE_DEPRECATED \
_Pragma("GCC diagnostic push") \

View File

@@ -3,17 +3,15 @@
# Agreement.
{
'conditions': [
[
'privacy_crypto_impl=="openssl"', {
'libraries': [
'-lcrypto',
],
}, # privacy_crypto_impl=="openssl"
'privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
'dependencies': [
'<(boringssl_libcrypto_path)',
], # dependencies
}, # privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"
],
['privacy_crypto_impl=="openssl"', {
'libraries': [
'-lcrypto',
],
}],
['privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
'dependencies': [
'<(boringssl_libcrypto_path)',
], # dependencies
}],
], # conditions
}

View File

@@ -3,18 +3,16 @@
# Agreement.
{
'conditions': [
[
'privacy_crypto_impl=="openssl"', {
'libraries': [
'-lcrypto',
'-lssl',
],
}, # privacy_crypto_impl=="openssl"
'privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
'dependencies': [
'<(boringssl_libssl_path)',
], # dependencies
}, # privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"
],
['privacy_crypto_impl=="openssl"', {
'libraries': [
'-lcrypto',
'-lssl',
],
}],
['privacy_crypto_impl=="boringssl" or privacy_crypto_impl=="apple"', {
'dependencies': [
'<(boringssl_libssl_path)',
], # dependencies
}],
], # conditions
}

View File

@@ -0,0 +1,171 @@
// 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

View File

@@ -0,0 +1,40 @@
// 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 "string_format.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory>
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);
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);
if (actual_size != desired_size) return false;
out->assign(buffer.get(), actual_size);
return true;
}
} // namespace wvutil

View File

@@ -0,0 +1,64 @@
// 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 "string_format.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <string>
namespace wvutil {
TEST(StringFormatTest, SignedInteger) {
constexpr char kFormat[] = "Version %d";
constexpr char kResult[] = "Version -123";
std::string result;
EXPECT_TRUE(FormatString(&result, kFormat, -123));
EXPECT_EQ(result, kResult);
}
TEST(StringFormatTest, UnsignedInteger) {
constexpr char kFormat[] = "Version %u";
constexpr char kResult[] = "Version 27";
std::string result;
EXPECT_TRUE(FormatString(&result, kFormat, 27));
EXPECT_EQ(result, kResult);
}
TEST(StringFormatTest, HexInteger) {
constexpr char kFormat[] = "Version %X";
constexpr char kResult[] = "Version FF";
std::string result;
EXPECT_TRUE(FormatString(&result, kFormat, 0xFF));
EXPECT_EQ(result, kResult);
}
TEST(StringFormatTest, Strings) {
constexpr char kFormat[] = "Hello, %s.";
constexpr char kResult[] = "Hello, DRM.";
std::string result;
EXPECT_TRUE(FormatString(&result, kFormat, "DRM"));
EXPECT_EQ(result, kResult);
}
TEST(StringFormatTest, Nothing) {
constexpr char kString[] = "No format fields.";
std::string result;
EXPECT_TRUE(FormatString(&result, kString));
EXPECT_EQ(result, kString);
}
TEST(StringFormatTest, NullOutput) {
constexpr char kString[] = "This will never be referenced.";
EXPECT_FALSE(FormatString(nullptr, kString));
}
TEST(StringFormatTest, NullFormat) {
std::string result;
EXPECT_FALSE(FormatString(&result, nullptr));
EXPECT_TRUE(result.empty());
}
} // namespace wvutil

View File

@@ -2,7 +2,9 @@
// source code may only be used and distributed under the Widevine License
// Agreement.
//
// Clock - A fake clock just for running tests.
// Clock - A fake clock just for running tests. This is used when running
// OEMCrypto unit tests. It is not used when tests include the CE CDM source
// code because that uses the clock in cdm/test_host.cpp instead.
#include <chrono>