Widevine MediaCas client code that works with Android R

This commit is contained in:
Lu Chen
2020-08-13 15:18:12 -07:00
parent ff9728aaa2
commit 0f6db6f751
243 changed files with 47012 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WV_UTIL_ADVANCE_IV_CTR_H_
#define WV_UTIL_ADVANCE_IV_CTR_H_
#include <stdint.h>
#include <string.h>
#include "string_conversions.h"
namespace wvutil {
// Advance an IV according to ISO-CENC's CTR modes. The lower half of the IV is
// split off and treated as an unsigned 64-bit integer, then incremented by the
// number of complete crypto blocks decrypted. The resulting value is then
// copied back into the IV over the previous lower half.
inline void AdvanceIvCtr(uint8_t (*subsample_iv)[16], size_t bytes) {
constexpr size_t kAesBlockSize = 16;
constexpr size_t kIvSize = kAesBlockSize;
constexpr size_t kCounterIndex = kIvSize / 2;
constexpr size_t kCounterSize = kIvSize / 2;
uint64_t counter;
static_assert(
sizeof(*subsample_iv) == kIvSize,
"The subsample_iv field is no longer the length of an AES-128 IV.");
static_assert(sizeof(counter) == kCounterSize,
"A uint64_t failed to be half the size of an AES-128 IV.");
// Defensive copy because the elements of the array may not be properly
// aligned
memcpy(&counter, &(*subsample_iv)[kCounterIndex], kCounterSize);
const size_t increment =
bytes / kAesBlockSize; // The truncation here is intentional
counter = htonll64(ntohll64(counter) + increment);
memcpy(&(*subsample_iv)[kCounterIndex], &counter, kCounterSize);
}
} // namespace wvutil
#endif // WV_UTIL_ADVANCE_IV_CTR_H_

View File

@@ -0,0 +1,20 @@
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WVCDM_UTIL_ARRAYSIZE_H_
#define WVCDM_UTIL_ARRAYSIZE_H_
#include <stdint.h>
namespace wvcdm {
// Returns the size of a fixed-length array.
template <typename T, size_t N>
constexpr size_t ArraySize(const T (&)[N]) {
return N;
}
} // namespace wvcdm
#endif // WVCDM_UTIL_ARRAYSIZE_H_

View File

@@ -0,0 +1,43 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef CAS_PROPERTIES_H
#define CAS_PROPERTIES_H
#include <string>
namespace wvcas {
// Properties methods must be implemented for a platform. The values returned
// describe the capabilities and configuration of a device using Widevine CAS.
class Properties {
private:
Properties(); // Not implemented
~Properties(); // NotImplemented
public:
// Sets the |company_name| field value to be populated in and EMM license
// request. Returns false if unable to set the value.
static bool GetCompanyName(std::string* company_name);
// Sets the |model_name| field value to be populated in and EMM license
// request. Returns false if unable to set the value.
static bool GetModelName(std::string* model_name);
// Sets the |product_name| field value to be populated in and EMM license
// request. Returns false if unable to set the value.
static bool GetProductName(std::string* product_name);
// Sets the |arch_name| field value to be populated in and EMM license
// request. Returns false if unable to set the value.
static bool GetArchitectureName(std::string* arch_name);
// Sets the |device_name| field value to be populated in and EMM license
// request. Returns false if unable to set the value.
static bool GetDeviceName(std::string* device_name);
// Returns a path to CAS oemcrypto library, either default,
// or overridden through system property.
// Returned path could be either absolute or relative.
// Returns false if unable to set the value.
static bool GetOEMCryptoPath(std::string* path);
};
} // namespace wvcas
#endif // CAS_PROPERTIES_H

117
wvutil/include/cdm_random.h Normal file
View File

@@ -0,0 +1,117 @@
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WVCDM_CORE_CDM_RANDOM_H_
#define WVCDM_CORE_CDM_RANDOM_H_
#include <mutex>
#include <random>
#include <string>
namespace wvcdm {
// CdmRandomGenerator is a thread safe, pseudo-random number generator.
// It's purpose is to simplified interface for C++11's <random> library.
// Some of the methods use a "device specific" random seed, if the
// compiler/device does not support device specific randomizers, then the
// actual value supplied may not be random. The generator is designed to
// meet the C++ named requirement UniformRandomBitGenerator to allow it to
// be used with standard library functions / class which are designed to
// work with the standard library generators.
class CdmRandomGenerator {
public:
// Result type of operator().
using result_type = unsigned int;
// Inclusive boundaries of operator().
static constexpr unsigned int min() { return 0; }
static constexpr unsigned int max() { return RAND_MAX; }
// The maximum number of bytes that can be generated at once for
// `RandomData()`.
static constexpr size_t kMaxRandomDataLength = 8192; // 8 kB
// Initializes the pseudo-random generator with a value from a device
// specific random number generator.
CdmRandomGenerator();
// Initializes the pseudo-random generator with the specified seed value.
explicit CdmRandomGenerator(unsigned int seed) : generator_(seed) {}
// All of these methods are thread-safe.
// Seeds the pseudo-random generator with a value from a device specific
// random number generator.
void Seed();
// Seeds the pseudo-random generator with the specified seed value.
// This is somewhat similar to `srand()` from the C standard library;
// except that the sequence generated from successive calls to `Rand()`
// will not necessarily be the same as they would be from the
// standard library `rand()`. This is due to the underlying pseudo-random
// generator that is used.
void Seed(unsigned int seed);
// Returns a pseudo-random integer.
// This is similar to `rand()` from the C standard library. The integer
// returned is in the range of [min(), max()].
unsigned int Rand();
// Allows for RNG to be callable.
unsigned int operator()() { return Rand(); }
// Returns a pseudo-random integer within the provided inclusive range.
uint64_t RandomInRange(uint64_t lower, uint64_t upper);
uint64_t RandomInRange(uint64_t upper) { return RandomInRange(0, upper); }
// Returns a byte string containing randomized bytes of the specified
// length.
// If |length| is greater than |CdmRandomGenerator::kMaxRandomDataLength|,
// then an error is logged and an empty string is returned.
std::string RandomData(size_t length);
// Random true/false using Bernoulli distribution of equal probability.
bool RandomBool();
private:
// Mutex is used to lock the object, and allowing it to be used
// concurrently in different threads.
std::mutex generator_lock_;
// The `default_random_engine` depends on the compiler used and
// potentially its version. This is important to know if you need to
// create reproducible tests between platforms.
std::default_random_engine generator_;
};
// Provides a static interface to a process-wide instance of
// CdmRandomGenerator.
class CdmRandom {
public:
static unsigned int Rand() { return GetInstance()->Rand(); }
static uint64_t RandomInRange(uint64_t lower, uint64_t upper) {
return GetInstance()->RandomInRange(lower, upper);
}
static uint64_t RandomInRange(uint64_t upper) {
return GetInstance()->RandomInRange(upper);
}
static std::string RandomData(size_t length) {
return GetInstance()->RandomData(length);
}
static bool RandomBool() { return GetInstance()->RandomBool(); }
private:
// These are intended to be used by tests if needed.
static void Seed(unsigned int seed) { GetInstance()->Seed(seed); }
static void Seed() { GetInstance()->Seed(); }
// Returns the process-wide instance of CdmRandomGenerator.
// It the global instance has not yet been created, then a new instance
// is created using a device-specific random seed.
static CdmRandomGenerator* GetInstance();
};
} // namespace wvcdm
#endif // WVCDM_CORE_CDM_RANDOM_H_

26
wvutil/include/clock.h Normal file
View File

@@ -0,0 +1,26 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// Clock - Platform independent interface for a time library
//
#ifndef WV_UTIL_CLOCK_H_
#define WV_UTIL_CLOCK_H_
#include <stdint.h>
namespace wvutil {
// Provides time related information. The implementation is platform dependent.
class Clock {
public:
Clock() {}
virtual ~Clock() {}
// Provides the number of seconds since an epoch - 01/01/1970 00:00 UTC
virtual int64_t GetCurrentTime();
};
} // namespace wvutil
#endif // WV_UTIL_CLOCK_H_

View File

@@ -0,0 +1,17 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WV_UTIL_DISALLOW_COPY_AND_ASSIGN_H_
#define WV_UTIL_DISALLOW_COPY_AND_ASSIGN_H_
namespace wvutil {
#define CORE_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
} // namespace wvutil
#endif // WVCAS_UTIL_DISALLOW_COPY_AND_ASSIGN_H_

View File

@@ -0,0 +1,77 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// File - Platform independent interface for a File class
//
#ifndef WV_UTIL_FILE_STORE_H_
#define WV_UTIL_FILE_STORE_H_
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include "disallow_copy_and_assign.h"
#include "platform.h"
#include "util_common.h"
namespace wvutil {
// File class. The implementation is platform dependent.
class CORE_UTIL_EXPORT File {
public:
File() {}
virtual ~File() {}
virtual ssize_t Read(char* buffer, size_t bytes) = 0;
virtual ssize_t Write(const char* buffer, size_t bytes) = 0;
friend class FileSystem;
CORE_DISALLOW_COPY_AND_ASSIGN(File);
};
class CORE_UTIL_EXPORT FileSystem {
public:
FileSystem();
FileSystem(const std::string& origin, void* extra_data);
virtual ~FileSystem();
class Impl;
// defines as bit flag
enum OpenFlags {
kNoFlags = 0,
kCreate = 1,
kReadOnly = 2, // defaults to read and write access
kTruncate = 4
};
virtual std::unique_ptr<File> Open(const std::string& file_path, int flags);
virtual bool Exists(const std::string& file_path);
virtual bool Remove(const std::string& file_path);
virtual ssize_t FileSize(const std::string& file_path);
// Return the filenames stored at dir_path.
// dir_path will be stripped from the returned names.
virtual bool List(const std::string& dir_path,
std::vector<std::string>* names);
const std::string& origin() const { return origin_; }
void set_origin(const std::string& origin);
const std::string& identifier() const { return identifier_; }
void set_identifier(const std::string& identifier);
bool IsGlobal() const { return identifier_.empty(); }
private:
std::unique_ptr<FileSystem::Impl> impl_;
std::string origin_;
std::string identifier_;
CORE_DISALLOW_COPY_AND_ASSIGN(FileSystem);
};
} // namespace wvutil
#endif // WV_UTIL_FILE_STORE_H_

View File

@@ -0,0 +1,28 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include <string>
#include <vector>
namespace wvutil {
const char kCurrentDirectory[] = ".";
const char kParentDirectory[] = "..";
const char kDirectoryDelimiter = '/';
const char kWildcard[] = "*";
bool IsCurrentOrParentDirectory(char* dir);
class FileUtils {
public:
static bool Exists(const std::string& src);
// The caller may only specifying a single wildcard
static bool Remove(const std::string& src);
static bool Copy(const std::string& src, const std::string& dest);
static bool List(const std::string& path, std::vector<std::string>* files);
static bool IsRegularFile(const std::string& path);
static bool IsDirectory(const std::string& path);
static bool CreateDirectory(const std::string& path);
};
} // namespace wvutil

54
wvutil/include/log.h Normal file
View File

@@ -0,0 +1,54 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// Log - Platform independent interface for a Logging class
//
#ifndef WV_UTIL_LOG_H_
#define WV_UTIL_LOG_H_
#include "util_common.h"
namespace wvutil {
// Simple logging class. The implementation is platform dependent.
typedef enum {
// This log level should only be used for |g_cutoff|, in order to silence all
// logging. It should never be passed to |Log()| as a log level.
LOG_SILENT = -1,
LOG_ERROR = 0,
LOG_WARN = 1,
LOG_INFO = 2,
LOG_DEBUG = 3,
LOG_VERBOSE = 4,
} LogPriority;
extern LogPriority g_cutoff;
// Enable/disable verbose logging (LOGV).
// 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();
CORE_UTIL_EXPORT void Log(const char* file, const char* function, int line,
LogPriority level, const char* fmt, ...);
// Log APIs
#ifndef LOGE
#define LOGE(...) Log(__FILE__, __func__, __LINE__, \
wvutil::LOG_ERROR, __VA_ARGS__)
#define LOGW(...) Log(__FILE__, __func__, __LINE__, \
wvutil::LOG_WARN, __VA_ARGS__)
#define LOGI(...) Log(__FILE__, __func__, __LINE__, \
wvutil::LOG_INFO, __VA_ARGS__)
#define LOGD(...) Log(__FILE__, __func__, __LINE__, \
wvutil::LOG_DEBUG, __VA_ARGS__)
#define LOGV(...) Log(__FILE__, __func__, __LINE__, \
wvutil::LOG_VERBOSE, __VA_ARGS__)
#endif
} // namespace wvutil
#endif // WV_UTIL_LOG_H_

31
wvutil/include/platform.h Normal file
View File

@@ -0,0 +1,31 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// Platform - Abstracts some utilities between platforms.
//
#ifndef WV_UTIL_PLATFORM_H_
#define WV_UTIL_PLATFORM_H_
#include "util_common.h"
#ifdef _WIN32
# include <BaseTsd.h>
# include <winsock2.h> // For htonl and ntohl.
# include <wtypes.h>
# define __PRETTY_FUNCTION__ __FUNCTION__
# undef NO_ERROR
# undef GetCurrentTime
# undef DeleteFile
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);
#else
# include <arpa/inet.h>
# include <sys/types.h>
# include <unistd.h>
#endif
#endif // WV_UTIL_PLATFORM_H_

65
wvutil/include/rw_lock.h Normal file
View File

@@ -0,0 +1,65 @@
// Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WVCAS_UTIL_RW_LOCK_H_
#define WVCAS_UTIL_RW_LOCK_H_
#include <stdint.h>
#include <condition_variable>
#include <mutex>
#include "disallow_copy_and_assign.h"
#include "util_common.h"
namespace wvcas {
// A simple reader-writer mutex implementation that mimics the one from C++17
class CORE_UTIL_EXPORT shared_mutex {
public:
shared_mutex() : reader_count_(0), has_writer_(false) {}
~shared_mutex();
// These methods take the mutex as a reader. They do not fulfill the
// SharedMutex requirement from the C++14 STL, but they fulfill enough of it
// to be used with |shared_lock| below.
void lock_shared();
void unlock_shared();
// These methods take the mutex as a writer. They fulfill the Mutex
// requirement from the C++11 STL so that this mutex can be used with
// |std::unique_lock|.
void lock() { lock_implementation(false); }
bool try_lock() { return lock_implementation(true); }
void unlock();
private:
bool lock_implementation(bool abort_if_unavailable);
uint32_t reader_count_;
bool has_writer_;
std::mutex mutex_;
std::condition_variable condition_variable_;
CORE_DISALLOW_COPY_AND_ASSIGN(shared_mutex);
};
// A simple reader lock implementation that mimics the one from C++14
template <typename Mutex>
class shared_lock {
public:
explicit shared_lock(Mutex& lock) : lock_(&lock) { lock_->lock_shared(); }
explicit shared_lock(Mutex* lock) : lock_(lock) { lock_->lock_shared(); }
~shared_lock() { lock_->unlock_shared(); }
private:
Mutex* lock_;
CORE_DISALLOW_COPY_AND_ASSIGN(shared_lock);
};
} // namespace wvcas
#endif // WVCAS_UTIL_RW_LOCK_H_

View File

@@ -0,0 +1,44 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WVCAS_UTIL_STRING_CONVERSIONS_H_
#define WVCAS_UTIL_STRING_CONVERSIONS_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "util_common.h"
namespace wvutil {
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);
CORE_UTIL_EXPORT std::string b2a_hex(const std::vector<uint8_t>& b);
CORE_UTIL_EXPORT std::string b2a_hex(const std::string& b);
CORE_UTIL_EXPORT std::string Base64Encode(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::vector<uint8_t> Base64Decode(
const std::string& bin_input);
CORE_UTIL_EXPORT std::string Base64SafeEncode(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::string Base64SafeEncodeNoPad(
const std::vector<uint8_t>& bin_input);
CORE_UTIL_EXPORT std::vector<uint8_t> Base64SafeDecode(
const std::string& bin_input);
CORE_UTIL_EXPORT std::string HexEncode(const uint8_t* bytes, unsigned size);
CORE_UTIL_EXPORT std::string IntToString(int value);
CORE_UTIL_EXPORT int64_t htonll64(int64_t x);
CORE_UTIL_EXPORT inline int64_t ntohll64(int64_t x) { return htonll64(x); }
CORE_UTIL_EXPORT std::string BytesToString(const uint8_t* bytes, unsigned size);
// Encode unsigned integer into a big endian formatted string
CORE_UTIL_EXPORT std::string EncodeUint32(unsigned int u);
} // namespace wvutil
#endif // WVCAS_UTIL_STRING_CONVERSIONS_H_

55
wvutil/include/timer.h Normal file
View File

@@ -0,0 +1,55 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
//
// Timer - Platform independent interface for a Timer class
//
#ifndef TIMER_H_
#define TIMER_H_
#include <stdint.h>
#include "disallow_copy_and_assign.h"
namespace wvutil {
// Timer Handler class.
//
// Derive from this class if you wish to receive events when the timer
// expires. Provide the handler when setting up a new Timer.
class TimerHandler {
public:
TimerHandler() {};
virtual ~TimerHandler() {};
virtual void OnTimerEvent() = 0;
};
// Timer class. The implementation is platform dependent.
//
// This class provides a simple recurring timer API. The class receiving
// timer expiry events should derive from TimerHandler.
// Specify the receiver class and the periodicty of timer events when
// the timer is initiated by calling Start.
class Timer {
public:
class Impl;
Timer();
~Timer();
bool Start(TimerHandler *handler, uint32_t time_in_secs);
void Stop();
bool IsRunning();
private:
Impl *impl_;
CORE_DISALLOW_COPY_AND_ASSIGN(Timer);
};
} // namespace wvcas
#endif // TIMER_H_

View File

@@ -0,0 +1,22 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WV_UTIL_UTIL_COMMON_H_
#define WV_UTIL_UTIL_COMMON_H_
#ifdef _WIN32
# ifdef CORE_UTIL_IMPLEMENTATION
# define CORE_UTIL_EXPORT __declspec(dllexport)
# else
# define CORE_UTIL_EXPORT __declspec(dllimport)
# endif
#else
# ifdef CORE_UTIL_IMPLEMENTATION
# define CORE_UTIL_EXPORT __attribute__((visibility("default")))
# else
# define CORE_UTIL_EXPORT
# endif
#endif
#endif // WV_UTIL_UTIL_COMMON_H_