Source release 14.1.0

This commit is contained in:
John W. Bruce
2018-06-29 15:59:47 -07:00
parent 3ab70cec4e
commit afa11a48a0
1941 changed files with 557780 additions and 105547 deletions

View File

@@ -1,4 +1,6 @@
// Copyright 2013 Google Inc. All Rights Reserved.
// 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.
/*********************************************************************
* OEMCryptoCENC.h
@@ -287,6 +289,8 @@ typedef enum OEMCrypto_Usage_Entry_Status {
* Platforms that have compilers that support packed structures, may use the
* following definition. Other platforms may use the header pst_report.h which
* defines a wrapper class.
*
* All fields are in network byte order.
*/
#if 0 // If your compiler supports __attribute__((packed)).
typedef struct {
@@ -369,11 +373,14 @@ typedef enum OEMCrypto_ProvisioningMethod {
#define OEMCrypto_Initialize _oecc01
#define OEMCrypto_Terminate _oecc02
#define OEMCrypto_InstallKeybox _oecc03
#define OEMCrypto_InstallRootKeyCertificate _oecc03
#define OEMCrypto_GetKeyData _oecc04
#define OEMCrypto_IsKeyboxValid _oecc05
#define OEMCrypto_IsRootKeyCertificateValid _oecc05
#define OEMCrypto_GetRandom _oecc06
#define OEMCrypto_GetDeviceID _oecc07
#define OEMCrypto_WrapKeybox _oecc08
#define OEMCrypto_WrapRootKeyCertificate _oecc08
#define OEMCrypto_OpenSession _oecc09
#define OEMCrypto_CloseSession _oecc10
#define OEMCrypto_DecryptCTR_V10 _oecc11
@@ -1491,36 +1498,38 @@ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr,
uint8_t subsample_flags);
/*
* OEMCrypto_WrapKeybox
* OEMCrypto_WrapRootKeyCertificate
*
* Description:
* During manufacturing, the keybox should be encrypted with the OEM root key
* and stored on the file system in a region that will not be erased during
* factory reset. As described in section 5.5.4, the keybox may be directly
* encrypted and stored on the device in a single step, or it may use the
* two-step WrapKeybox/InstallKeybox approach. When the Widevine DRM plugin
* initializes, it will look for a wrapped keybox in the file
* /factory/wv.keys and install it into the security processor by calling
* OEMCrypto_InstallKeybox().
*
* OEMCrypto_WrapKeybox() is used to generate an OEM-encrypted keybox that
* may be passed to OEMCrypto_InstallKeybox() for provisioning. The keybox
* may be either passed in the clear or previously encrypted with a transport
* key. If a transport key is supplied, the keybox is first decrypted with
* the transport key before being wrapped with the OEM root key. This
* function is only needed if the provisioning method involves saving the
* keybox to the file system.
* A device should be provisioned at the factory with either an OEM
* Certificate or a keybox. We will call this data the root of trust. During
* manufacturing, the root of trust should be encrypted with the OEM root key
* and stored on the file system in a region that will not be erased during
* factory reset. This function may be used by legacy systems that use the
* two-step WrapRootKeyCertificate/InstallRootKeyCertificate approach. When
* the Widevine DRM plugin initializes, it will look for a wrapped root of
* trust in the file /factory/wv.keys and install it into the security
* processor by calling OEMCrypto_InstallRootKeyCertificate().
*
* OEMCrypto_WrapRootKeyCertificate() is used to generate an OEM-encrypted
* root of trust that may be passed to OEMCrypto_InstallRootKeyCertificate()
* for provisioning. The root of trust may be either passed in the clear or
* previously encrypted with a transport key. If a transport key is supplied,
* the keybox is first decrypted with the transport key before being wrapped
* with the OEM root key. This function is only needed if the root of trust
* provisioning method involves saving the keybox to the file system.
*
* Parameters:
* keybox (in) - pointer to Keybox data to encrypt. May be NULL on the first
* call to test size of wrapped keybox. The keybox may either be clear or
* previously encrypted.
* keyboxLength (in) - length the keybox data in bytes
* wrappedKeybox (out) Pointer to wrapped keybox
* wrappedKeyboxLength (out) Pointer to the length of the wrapped keybox in
* rot (in) - pointer to root of trust data to encrypt. May be NULL on the
* first call to test size of wrapped keybox. The keybox may either be
* clear or previously encrypted.
* rotLength (in) - length the rot data in bytes
* wrappedRot (out) Pointer to wrapped rot
* wrappedRotLength (out) Pointer to the length of the wrapped keybox in
* bytes
* transportKey (in) Optional. AES transport key. If provided, the keybox
* parameter was previously encrypted with this key. The keybox will be
* transportKey (in) Optional. AES transport key. If provided, the rot
* parameter was previously encrypted with this key. The rot will be
* decrypted with the transport key using AES-CBC and a null IV.
* transportKeyLength (in) Optional. Number of bytes in the transportKey, if
* used.
@@ -1539,26 +1548,29 @@ OEMCryptoResult OEMCrypto_CopyBuffer(const uint8_t* data_addr,
* Version:
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t* keybox, size_t keyBoxLength,
uint8_t* wrappedKeybox,
size_t* wrappedKeyBoxLength,
const uint8_t* transportKey,
size_t transportKeyLength);
OEMCryptoResult OEMCrypto_WrapRootKeyCertificate(const uint8_t* rot, size_t rotLength,
uint8_t* wrappedRot,
size_t* wrappedRotLength,
const uint8_t* transportKey,
size_t transportKeyLength);
/*
* OEMCrypto_InstallKeybox
* OEMCrypto_InstallRootKeyCertificate
*
* Description:
* Decrypts a wrapped keybox and installs it in the security processor. The
* keybox is unwrapped then encrypted with the OEM root key. This function is
* called from the Widevine DRM plugin at initialization time if there is no
* valid keybox installed. It looks for a wrapped keybox in the file
* /factory/wv.keys and if it is present, will read the file and call
* OEMCrypto_InstallKeybox() with the contents of the file.
*
* Decrypts a wrapped root of trust and installs it in the security processor.
* The root of trust is unwrapped then encrypted with the OEM root key. This
* function is called from the Widevine DRM plugin at initialization time if
* there is no valid root of trust installed. It looks for wrapped data in
* the file /factory/wv.keys and if it is present, will read the file and call
* OEMCrypto_InstallRootKeyCertificate() with the contents of the file. This
* function is only needed if the factory provisioning method involves saving
* the keybox to the file system.
*
* Parameters:
* keybox (in) - pointer to encrypted Keybox data as input
* keyboxLength (in) - length of the keybox data in bytes
* rot (in) - pointer to encrypted data as input
* rotLength (in) - length of the data in bytes
*
* Threading:
* This function is not called simultaneously with any other functions.
@@ -1573,8 +1585,8 @@ OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t* keybox, size_t keyBoxLength,
* Version:
* This method is supported in all API versions.
*/
OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
size_t keyBoxLength);
OEMCryptoResult OEMCrypto_InstallRootKeyCertificate(const uint8_t* rot,
size_t rotLength);
/*
* OEMCrypto_GetProvisioningMethod
@@ -1669,10 +1681,12 @@ OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(OEMCrypto_SESSION session,
OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t *buffer, size_t length);
/*
* OEMCrypto_IsKeyboxValid
* OEMCrypto_IsRootKeyCertificateValid
*
* Description:
* Validate the Widevine Keybox stored on the device.
*
* If the device has a keybox, this validates the Widevine Keybox loaded into
* the security processor device.
*
* The API performs two verification steps on the Keybox. It first verifies
* the MAGIC field contains a valid signature (must be 'kbox'). The API then
@@ -1680,6 +1694,9 @@ OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t *buffer, size_t length);
* checksum to the CRC stored in the Keybox. The CRC is computed over the
* entire Keybox excluding the 4 CRC bytes (i.e. Keybox[0..123]).
*
* If the device has an OEM Certificate, this validates the certificate private
* key.
*
* Parameters:
* none
*
@@ -1690,11 +1707,13 @@ OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t *buffer, size_t length);
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_BAD_MAGIC
* OEMCrypto_ERROR_BAD_CRC
* OEMCrypto_ERROR_KEYBOX_INVALID
* OEMCrypto_ERROR_NOT_IMPLEMENTED
*
* Version:
* This method is supported by all API versions.
*/
OEMCryptoResult OEMCrypto_IsKeyboxValid(void);
OEMCryptoResult OEMCrypto_IsRootKeyCertificateValid(void);
/*
* OEMCrypto_GetDeviceID

View File

@@ -1,29 +0,0 @@
// Copyright 2017 Google Inc. All Rights Reserved
/*********************************************************************
* level3_file_system.h
*
* File system for OEMCrypto Level3 file operations.
*********************************************************************/
#ifndef LEVEL3_FILE_SYSTEM_H_
#define LEVEL3_FILE_SYSTEM_H_
#include <stdlib.h>
namespace wvoec3 {
class OEMCrypto_Level3FileSystem {
public:
virtual ~OEMCrypto_Level3FileSystem() {}
virtual ssize_t Read(const char *filename, void *buffer, size_t size) = 0;
virtual ssize_t Write(const char *filename, const void *buffer,
size_t size) = 0;
virtual bool Exists(const char *filename) = 0;
virtual ssize_t FileSize(const char *filename) = 0;
virtual bool Remove(const char *filename) = 0;
};
} // namespace wvoec3
#endif

View File

@@ -1,65 +0,0 @@
// Copyright 2014 Google Inc. All Rights Reserved.
#ifndef WVOEC_OEMCRYPTO_LOGGING_H_
#define WVOEC_OEMCRYPTO_LOGGING_H_
#include <iostream>
#include <string>
#include "OEMCryptoCENC.h"
#include "log.h"
namespace wvoec_mock {
// The constants below represent integers with a single "on" bit that
// represents categories of logging This allows users to specify with
// more precision what they want to log. LogCategoryEnabled(category)
// is used to see if the category passed in the parameters is to
// be logged based on the current settings. Categories can be combines
// using the | (or) bitwise operator. For example
// LogCategoryEnabled(category1 | category2) will return true if
// category1 and/or category2 are set to logging.
const int kLoggingTraceOEMCryptoCalls = 0x01; // All except decrypt calls.
const int kLoggingDumpContentKeys = 0x02;
const int kLoggingDumpKeyControlBlocks = 0x04;
const int kLoggingDumpDerivedKeys = 0x08;
const int kLoggingTraceNonce = 0x10;
const int kLoggingTraceDecryption = 0x20;
const int kLoggingTraceUsageTable = 0x40;
const int kLoggingTraceDecryptCalls = 0x80;
const int kLoggingDumpTraceAll = 0xFF;
void SetLoggingSettings(int level, int categories);
// set level of logging
void SetLoggingLevel(int level);
void TurnOffLoggingForAllCategories();
// Returns true if the category passed is set to logging.
// Returns false otherwise. The category constant declared
// above are passed.
bool LogCategoryEnabled(int category);
// Turn on logging for the categories passed.
void AddLoggingForCategories(int categories);
// Turn off logging for the categories passed.
void RemoveLoggingForCategories(int categories);
void dump_hex_helper(std::string& buffer, std::string name,
const uint8_t* vector, size_t length);
void dump_hex(std::string name, const uint8_t* vector, size_t length);
void dump_array_part_helper(std::string& buffer, std::string array,
size_t index, std::string name,
const uint8_t* vector, size_t length);
void dump_array_part(std::string array, size_t index, std::string name,
const uint8_t* vector, size_t length);
} // namespace wvoec_mock
#endif // WVOEC_OEMCRYPTO_LOGGING_H_

View File

@@ -0,0 +1,67 @@
// 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_OEMCRYPTO_TYPES_H_
#define WV_OEMCRYPTO_TYPES_H_
#include <stdint.h>
namespace wvoec {
// This is the format of a Widevine keybox.
typedef struct WidevineKeybox { // 128 bytes total.
// C character string identifying the device. Null terminated.
uint8_t device_id_[32];
// 128 bit AES key assigned to device. Generated by Widevine.
uint8_t device_key_[16];
// Key Data. Encrypted data.
uint8_t data_[72];
// Constant code used to recognize a valid keybox "kbox" = 0x6b626f78.
uint8_t magic_[4];
// The CRC checksum of the first 124 bytes of the keybox.
uint8_t crc_[4];
} WidevineKeybox;
// Key Control Block Bit Masks:
const uint32_t kControlObserveDataPath = (1<<31);
const uint32_t kControlObserveHDCP = (1<<30);
const uint32_t kControlObserveCGMS = (1<<29);
const uint32_t kControlRequireAntiRollbackHardware = (1<<28);
const uint32_t kSharedLicense = (1<<23);
const uint32_t kControlSRMVersionRequired = (1<<22);
const uint32_t kControlDisableAnalogOutput = (1<<21);
const uint32_t kControlSecurityPatchLevelShift = 15;
const uint32_t kControlSecurityPatchLevelMask =
(0x3F<<kControlSecurityPatchLevelShift);
const uint32_t kControlReplayMask = (0x03<<13);
const uint32_t kControlNonceRequired = (0x01<<13);
const uint32_t kControlNonceOrEntry = (0x02<<13);
const uint32_t kControlHDCPVersionShift = 9;
const uint32_t kControlHDCPVersionMask = (0x0F<<kControlHDCPVersionShift);
const uint32_t kControlAllowEncrypt = (1<<8);
const uint32_t kControlAllowDecrypt = (1<<7);
const uint32_t kControlAllowSign = (1<<6);
const uint32_t kControlAllowVerify = (1<<5);
const uint32_t kControlDataPathSecure = (1<<4);
const uint32_t kControlNonceEnabled = (1<<3);
const uint32_t kControlHDCPRequired = (1<<2);
const uint32_t kControlCGMSMask = (0x03);
const uint32_t kControlCGMSCopyFreely = (0x00);
const uint32_t kControlCGMSCopyOnce = (0x02);
const uint32_t kControlCGMSCopyNever = (0x03);
// Various constants and sizes:
static const size_t KEY_CONTROL_SIZE = 16;
static const size_t KEY_ID_SIZE = 16;
static const size_t KEY_IV_SIZE = 16;
static const size_t KEY_PAD_SIZE = 16;
static const size_t KEY_SIZE = 16;
static const size_t MAC_KEY_SIZE = 32;
static const size_t KEYBOX_KEY_DATA_SIZE = 72;
static const size_t SRM_REQUIREMENT_SIZE = 12;
} // namespace wvoec
#endif // WV_OEMCRYPTO_TYPES_H_

View File

@@ -0,0 +1,148 @@
// 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.
/*********************************************************************
* pst_report.h
*
* Reference APIs needed to support Widevine's crypto algorithms.
*********************************************************************/
#ifndef PST_REPORT_H_
#define PST_REPORT_H_
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "OEMCryptoCENC.h"
#include "string_conversions.h" // needed for htonll64.
namespace wvcdm {
class Unpacked_PST_Report {
public:
// This object does not own the buffer, and does not check that buffer
// is not null.
Unpacked_PST_Report(uint8_t *buffer) : buffer_(buffer) {}
// Copy and move semantics of this class is like that of a pointer.
Unpacked_PST_Report(const Unpacked_PST_Report& other) :
buffer_(other.buffer_) {}
Unpacked_PST_Report& operator=(const Unpacked_PST_Report& other) {
buffer_ = other.buffer_;
return *this;
}
size_t report_size() const {
return pst_length() + kraw_pst_report_size;
}
static size_t report_size(size_t pst_length) {
return pst_length + kraw_pst_report_size;
}
uint8_t status() const {
return static_cast<uint8_t>(* (buffer_ + kstatus_offset));
}
void set_status(uint8_t value) {
buffer_[kstatus_offset] = value;
}
uint8_t* signature() {
return buffer_ + ksignature_offset;
}
uint8_t clock_security_level() const {
return static_cast<uint8_t>(* (buffer_ + kclock_security_level_offset));
}
void set_clock_security_level(uint8_t value) {
buffer_[kclock_security_level_offset] = value;
}
uint8_t pst_length() const {
return static_cast<uint8_t>(* (buffer_ + kpst_length_offset));
}
void set_pst_length(uint8_t value) {
buffer_[kpst_length_offset] = value;
}
uint8_t padding() const {
return static_cast<uint8_t>(* (buffer_ + kpadding_offset));
}
void set_padding(uint8_t value) {
buffer_[kpadding_offset] = value;
}
// In host byte order.
int64_t seconds_since_license_received() const {
int64_t time;
memcpy(&time, buffer_ + kseconds_since_license_received_offset,
sizeof(int64_t));
return ntohll64(time);
}
// Parameter time is in host byte order.
void set_seconds_since_license_received(int64_t time) const {
time = ntohll64(time);
memcpy(buffer_ + kseconds_since_license_received_offset, &time,
sizeof(int64_t));
}
// In host byte order.
int64_t seconds_since_first_decrypt() const {
int64_t time;
memcpy(&time, buffer_ + kseconds_since_first_decrypt_offset,
sizeof(int64_t));
return ntohll64(time);
}
// Parameter time is in host byte order.
void set_seconds_since_first_decrypt(int64_t time) const {
time = ntohll64(time);
memcpy(buffer_ + kseconds_since_first_decrypt_offset, &time,
sizeof(int64_t));
}
// In host byte order.
int64_t seconds_since_last_decrypt() const {
int64_t time;
memcpy(&time, buffer_ + kseconds_since_last_decrypt_offset,
sizeof(int64_t));
return ntohll64(time);
}
// Parameter time is in host byte order.
void set_seconds_since_last_decrypt(int64_t time) const {
time = ntohll64(time);
memcpy(buffer_ + kseconds_since_last_decrypt_offset, &time,
sizeof(int64_t));
}
uint8_t* pst() {
return (buffer_ + kpst_offset);
}
private:
uint8_t *buffer_;
// Size of the PST_Report without the pst string.
static const size_t kraw_pst_report_size = 48;
static const size_t ksignature_offset = 0;
static const size_t kstatus_offset = 20;
static const size_t kclock_security_level_offset = 21;
static const size_t kpst_length_offset = 22;
static const size_t kpadding_offset = 23;
static const size_t kseconds_since_license_received_offset = 24;
static const size_t kseconds_since_first_decrypt_offset = 32;
static const size_t kseconds_since_last_decrypt_offset = 40;
static const size_t kpst_offset = 48;
};
} // namespace wvcdm
#endif // PST_REPORT_H_

View File

@@ -1,11 +1,12 @@
# Copyright 2017 Google Inc. All Rights Reserved.
# 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.
#
# Builds under the CDM ./build.py (target platform) build system
# Refer to the distribution package's README for details.
{
'variables': {
'oemcrypto_lib%': '',
'oemcrypto_stubs%': '',
'openssl_config%': 'system',
'openssl_target%': '',
},

View File

@@ -1,4 +1,6 @@
# Copyright 2017 Google Inc. All Rights Reserved.
# 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 this in any custom unit test targets.
# Does not include the test runner main.
@@ -14,7 +16,7 @@
'include_dirs': [
'../../../core/include', # log.h
'../../include',
'../../mock/src', # oemcrypto_key_mock.h
'../../ref/src', # oemcrypto_key_ref.h
'../',
'../../../cdm/test',
],
@@ -32,23 +34,15 @@
'../../../third_party/gmock.gyp:gtest',
],
'conditions': [
['oemcrypto_stubs!=""', {
'dependencies': [
'../../stubs/stubs.gyp:oec_stubs_v<(oemcrypto_version)',
],
}, {
'conditions': [
['oemcrypto_lib==""', {
'dependencies': [
'../../mock/oec_mock.gyp:oec_mock',
],
}, {
'libraries': [
'../../../third_party/fuzz/platforms/x86-64/libFuzzer.a',
'<(oemcrypto_lib)',
],
}],
],
['oemcrypto_lib==""', {
'includes': [
'../../ref/oec_ref.gypi',
],
}, {
'libraries': [
'../../../third_party/fuzz/platforms/x86-64/libFuzzer.a',
'<(oemcrypto_lib)',
],
}],
],
}

View File

@@ -1,4 +1,6 @@
# Copyright 2017 Google Inc. All rights reserved.
# 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.
{
# Here you can set platform-specific compiler settings.
'target_defaults': {

View File

@@ -1,10 +1,14 @@
// Copyright 2016 Google Inc. All Rights Reserved.
// 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.
//
// OEMCrypto device features for unit tests
//
#include "oec_device_features.h"
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>
@@ -141,6 +145,11 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
if (api_version < 12) FilterOut(&filter, "*API12*");
if (api_version < 13) FilterOut(&filter, "*API13*");
if (api_version < 14) FilterOut(&filter, "*API14*");
// Some tests may require root access. If user is not root, filter these tests
// out.
if (getuid()) {
FilterOut(&filter, "UsageTableTest.TimeRollbackPrevention");
}
// Performance tests take a long time. Filter them out if they are not
// specifically requested.
if (filter.find("Performance") == std::string::npos) {

View File

@@ -4,7 +4,7 @@
#include <string>
#include "OEMCryptoCENC.h"
#include "wv_keybox.h"
#include "oemcrypto_types.h"
namespace wvoec {

View File

@@ -1,4 +1,6 @@
// Copyright 2016 Google Inc. All Rights Reserved.
// 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.
//
// OEMCrypto unit tests
//
@@ -24,14 +26,12 @@
#include <vector>
#include "OEMCryptoCENC.h"
#include "disallow_copy_and_assign.h"
#include "log.h"
#include "oec_device_features.h"
#include "oemcrypto_key_mock.h"
#include "test_rsa_key.h"
#include "oemcrypto_types.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h"
#include "wv_keybox.h"
#include "test_rsa_key.h"
using namespace std;
@@ -100,14 +100,14 @@ Session::Session()
: open_(false),
forced_session_id_(false),
session_id_(0),
mac_key_server_(wvcdm::MAC_KEY_SIZE),
mac_key_client_(wvcdm::MAC_KEY_SIZE),
enc_key_(wvcdm::KEY_SIZE),
mac_key_server_(MAC_KEY_SIZE),
mac_key_client_(MAC_KEY_SIZE),
enc_key_(KEY_SIZE),
public_rsa_(0),
message_size_(sizeof(MessageData)),
num_keys_(4), // Most tests only use 4 keys.
// Other tests will explicitly call set_num_keys.
has_entitlement_license_(false) {
// Most tests only use 4 keys. Other tests will explicitly call
// set_num_keys.
num_keys_(4) {
// Stripe the padded message.
for (size_t i = 0; i < sizeof(padded_message_.padding); i++) {
padded_message_.padding[i] = i % 0x100;
@@ -185,7 +185,7 @@ void Session::DeriveKey(const uint8_t* key, const vector<uint8_t>& context,
CMAC_CTX* cmac_ctx = CMAC_CTX_new();
ASSERT_NE(static_cast<void*>(NULL), cmac_ctx);
ASSERT_EQ(1, CMAC_Init(cmac_ctx, key, wvcdm::KEY_SIZE, cipher, 0));
ASSERT_EQ(1, CMAC_Init(cmac_ctx, key, KEY_SIZE, cipher, 0));
std::vector<uint8_t> message;
message.push_back(counter);
@@ -267,9 +267,9 @@ void Session::LoadTestKeys(const std::string& pst, bool new_mac_keys) {
key_array_, pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE,
wvcdm::MAC_KEY_SIZE);
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE,
MAC_KEY_SIZE);
} else {
ASSERT_EQ(
OEMCrypto_SUCCESS,
@@ -297,9 +297,9 @@ void Session::LoadEnitlementTestKeys(const std::string& pst,
key_array_, pst_ptr, pst.length(), NULL,
OEMCrypto_EntitlementLicense));
// Update new generated keys.
memcpy(&mac_key_server_[0], license_.mac_keys, wvcdm::MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + wvcdm::MAC_KEY_SIZE,
wvcdm::MAC_KEY_SIZE);
memcpy(&mac_key_server_[0], license_.mac_keys, MAC_KEY_SIZE);
memcpy(&mac_key_client_[0], license_.mac_keys + MAC_KEY_SIZE,
MAC_KEY_SIZE);
} else {
ASSERT_EQ(
expected_sts,
@@ -311,7 +311,6 @@ void Session::LoadEnitlementTestKeys(const std::string& pst,
}
void Session::FillEntitledKeyArray() {
has_entitlement_license_ = true;
for (size_t i = 0; i < num_keys_; ++i) {
EntitledContentKeyData* key_data = &entitled_key_data_[i];
@@ -478,7 +477,7 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
memset(license_.keys[i].key_id, i, license_.keys[i].key_id_length);
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_data,
sizeof(license_.keys[i].key_data)));
license_.keys[i].key_data_length = wvcdm::KEY_SIZE;
license_.keys[i].key_data_length = KEY_SIZE;
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_iv,
sizeof(license_.keys[i].key_iv)));
EXPECT_EQ(1, GetRandBytes(license_.keys[i].control_iv,
@@ -492,14 +491,14 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
} else if (global_features.api_version == 12) {
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
memcpy(license_.keys[i].control.verification, "kc12", 4);
} else if (control & wvoec_mock::kControlSecurityPatchLevelMask) {
} else if (control & wvoec::kControlSecurityPatchLevelMask) {
// For versions before 12, we require the special key control block only
// when there are newer features present.
memcpy(license_.keys[i].control.verification, "kc11", 4);
} else if (control & wvoec_mock::kControlRequireAntiRollbackHardware) {
} else if (control & wvoec::kControlRequireAntiRollbackHardware) {
memcpy(license_.keys[i].control.verification, "kc10", 4);
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
wvoec_mock::kControlReplayMask)) {
} else if (control & (wvoec::kControlHDCPVersionMask |
wvoec::kControlReplayMask)) {
memcpy(license_.keys[i].control.verification, "kc09", 4);
} else {
memcpy(license_.keys[i].control.verification, "kctl", 4);
@@ -525,7 +524,7 @@ void Session::FillSimpleEntitlementMessage(
memset(license_.keys[i].key_id, i, license_.keys[i].key_id_length);
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_data,
sizeof(license_.keys[i].key_data)));
license_.keys[i].key_data_length = wvcdm::KEY_SIZE * 2; // AES-256 keys
license_.keys[i].key_data_length = KEY_SIZE * 2; // AES-256 keys
EXPECT_EQ(1, GetRandBytes(license_.keys[i].key_iv,
sizeof(license_.keys[i].key_iv)));
EXPECT_EQ(1, GetRandBytes(license_.keys[i].control_iv,
@@ -539,14 +538,14 @@ void Session::FillSimpleEntitlementMessage(
} else if (global_features.api_version == 12) {
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
memcpy(license_.keys[i].control.verification, "kc12", 4);
} else if (control & wvoec_mock::kControlSecurityPatchLevelMask) {
} else if (control & wvoec::kControlSecurityPatchLevelMask) {
// For versions before 12, we require the special key control block only
// when there are newer features present.
memcpy(license_.keys[i].control.verification, "kc11", 4);
} else if (control & wvoec_mock::kControlRequireAntiRollbackHardware) {
} else if (control & wvoec::kControlRequireAntiRollbackHardware) {
memcpy(license_.keys[i].control.verification, "kc10", 4);
} else if (control & (wvoec_mock::kControlHDCPVersionMask |
wvoec_mock::kControlReplayMask)) {
} else if (control & (wvoec::kControlHDCPVersionMask |
wvoec::kControlReplayMask)) {
memcpy(license_.keys[i].control.verification, "kc09", 4);
} else {
memcpy(license_.keys[i].control.verification, "kctl", 4);
@@ -590,22 +589,21 @@ void Session::EncryptAndSign() {
encrypted_license() = license_;
uint8_t iv_buffer[16];
memcpy(iv_buffer, &license_.mac_key_iv[0], wvcdm::KEY_IV_SIZE);
memcpy(iv_buffer, &license_.mac_key_iv[0], KEY_IV_SIZE);
AES_KEY aes_key;
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_cbc_encrypt(&license_.mac_keys[0], &encrypted_license().mac_keys[0],
2 * wvcdm::MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
2 * MAC_KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
int key_size = has_entitlement_license() ? 256 : 128;
for (unsigned int i = 0; i < num_keys_; i++) {
memcpy(iv_buffer, &license_.keys[i].control_iv[0], wvcdm::KEY_IV_SIZE);
AES_set_encrypt_key(&license_.keys[i].key_data[0], key_size, &aes_key);
memcpy(iv_buffer, &license_.keys[i].control_iv[0], KEY_IV_SIZE);
AES_set_encrypt_key(&license_.keys[i].key_data[0], 128, &aes_key);
AES_cbc_encrypt(
reinterpret_cast<const uint8_t*>(&license_.keys[i].control),
reinterpret_cast<uint8_t*>(&encrypted_license().keys[i].control),
wvcdm::KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
KEY_SIZE, &aes_key, iv_buffer, AES_ENCRYPT);
memcpy(iv_buffer, &license_.keys[i].key_iv[0], wvcdm::KEY_IV_SIZE);
memcpy(iv_buffer, &license_.keys[i].key_iv[0], KEY_IV_SIZE);
AES_set_encrypt_key(&enc_key_[0], 128, &aes_key);
AES_cbc_encrypt(
&license_.keys[i].key_data[0], &encrypted_license().keys[i].key_data[0],
@@ -620,14 +618,14 @@ void Session::EncryptAndSign() {
void Session::EncryptProvisioningMessage(
RSAPrivateKeyMessage* data, RSAPrivateKeyMessage* encrypted,
const vector<uint8_t>& encryption_key) {
ASSERT_EQ(encryption_key.size(), wvcdm::KEY_SIZE);
ASSERT_EQ(encryption_key.size(), KEY_SIZE);
*encrypted = *data;
size_t padding = wvcdm::KEY_SIZE - (data->rsa_key_length % wvcdm::KEY_SIZE);
size_t padding = KEY_SIZE - (data->rsa_key_length % KEY_SIZE);
memset(data->rsa_key + data->rsa_key_length, static_cast<uint8_t>(padding),
padding);
encrypted->rsa_key_length = data->rsa_key_length + padding;
uint8_t iv_buffer[16];
memcpy(iv_buffer, &data->rsa_key_iv[0], wvcdm::KEY_IV_SIZE);
memcpy(iv_buffer, &data->rsa_key_iv[0], KEY_IV_SIZE);
AES_KEY aes_key;
AES_set_encrypt_key(&encryption_key[0], 128, &aes_key);
AES_cbc_encrypt(&data->rsa_key[0], &encrypted->rsa_key[0],
@@ -740,8 +738,8 @@ void Session::TestDecryptCTR(bool select_key_first,
for (size_t i = 0; i < unencryptedData.size(); i++)
unencryptedData[i] = i % 256;
EXPECT_EQ(1, GetRandBytes(&unencryptedData[0], unencryptedData.size()));
vector<uint8_t> encryptionIv(wvcdm::KEY_IV_SIZE);
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], wvcdm::KEY_IV_SIZE));
vector<uint8_t> encryptionIv(KEY_IV_SIZE);
EXPECT_EQ(1, GetRandBytes(&encryptionIv[0], KEY_IV_SIZE));
vector<uint8_t> encryptedData(unencryptedData.size());
EncryptCTR(unencryptedData, license_.keys[key_index].key_data,
&encryptionIv[0], &encryptedData);
@@ -893,7 +891,7 @@ void Session::MakeRSACertificate(struct RSAPrivateKeyMessage* encrypted,
memcpy(message.rsa_key, rsa_key.data(), rsa_key.size());
message.rsa_key_length = rsa_key.size();
}
EXPECT_EQ(1, GetRandBytes(message.rsa_key_iv, wvcdm::KEY_IV_SIZE));
EXPECT_EQ(1, GetRandBytes(message.rsa_key_iv, KEY_IV_SIZE));
message.nonce = nonce_;
EncryptProvisioningMessage(&message, encrypted, *encryption_key);
@@ -1196,7 +1194,7 @@ void Session::VerifyPST(const Test_PST_Report& expected) {
char* pst_ptr = reinterpret_cast<char *>(computed.pst());
std::string computed_pst(pst_ptr, pst_ptr + computed.pst_length());
ASSERT_EQ(expected.pst, computed_pst);
time_t now = time(NULL);
time_t now = time(NULL);
int64_t age = now - expected.time_created; // How old is this report.
EXPECT_NEAR(expected.seconds_since_license_received + age,
computed.seconds_since_license_received(),
@@ -1232,13 +1230,10 @@ static int64_t MaybeAdjustTime(int64_t t, time_t now) {
return t;
}
void Session::GenerateVerifyReport(const std::string& pst,
OEMCrypto_Usage_Entry_Status status,
int64_t time_license_received,
int64_t time_first_decrypt,
int64_t time_last_decrypt) {
ASSERT_NO_FATAL_FAILURE(GenerateReport(pst));
Test_PST_Report expected(pst, status);
void Session::VerifyReport(Test_PST_Report expected,
int64_t time_license_received,
int64_t time_first_decrypt,
int64_t time_last_decrypt) {
time_t now = time(NULL);
expected.seconds_since_license_received =
MaybeAdjustTime(time_license_received, now);
@@ -1248,6 +1243,17 @@ void Session::GenerateVerifyReport(const std::string& pst,
ASSERT_NO_FATAL_FAILURE(VerifyPST(expected));
}
void Session::GenerateVerifyReport(const std::string& pst,
OEMCrypto_Usage_Entry_Status status,
int64_t time_license_received,
int64_t time_first_decrypt,
int64_t time_last_decrypt) {
ASSERT_NO_FATAL_FAILURE(GenerateReport(pst));
Test_PST_Report expected(pst, status);
ASSERT_NO_FATAL_FAILURE(VerifyReport(expected, time_license_received,
time_first_decrypt, time_last_decrypt));
}
void Session::CreateOldEntry(const Test_PST_Report& report) {
OEMCryptoResult result = OEMCrypto_CreateOldUsageEntry(
report.seconds_since_license_received,

View File

@@ -1,7 +1,9 @@
#ifndef CDM_OEC_SESSION_UTIL_H_
#define CDM_OEC_SESSION_UTIL_H_
// Copyright 2016 Google Inc. All Rights Reserved.
// 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.
//
// OEMCrypto unit tests
//
@@ -10,9 +12,9 @@
#include <vector>
#include "oec_device_features.h"
#include "oemcrypto_types.h"
#include "pst_report.h"
#include "test_keybox.h"
#include "wv_cdm_constants.h"
using namespace std;
@@ -65,10 +67,10 @@ const size_t kMaxDecryptSize = 100 * 1024; // In specification.
typedef struct {
uint8_t key_id[kTestKeyIdMaxLength];
size_t key_id_length;
uint8_t key_data[wvcdm::MAC_KEY_SIZE];
uint8_t key_data[MAC_KEY_SIZE];
size_t key_data_length;
uint8_t key_iv[wvcdm::KEY_IV_SIZE];
uint8_t control_iv[wvcdm::KEY_IV_SIZE];
uint8_t key_iv[KEY_IV_SIZE];
uint8_t control_iv[KEY_IV_SIZE];
KeyControlBlock control;
// Note: cipher_mode may not be part of a real signed message. For these
// tests, it is convenient to keep it in this structure anyway.
@@ -78,8 +80,8 @@ typedef struct {
// This structure will be signed to simulate a message from the server.
struct MessageData {
MessageKeyData keys[kMaxNumKeys];
uint8_t mac_key_iv[wvcdm::KEY_IV_SIZE];
uint8_t mac_keys[2 * wvcdm::MAC_KEY_SIZE];
uint8_t mac_key_iv[KEY_IV_SIZE];
uint8_t mac_keys[2 * MAC_KEY_SIZE];
uint8_t pst[kMaxPSTLength];
};
@@ -87,7 +89,7 @@ struct MessageData {
// server.
struct RSAPrivateKeyMessage {
uint8_t rsa_key[kMaxTestRSAKeyLength];
uint8_t rsa_key_iv[wvcdm::KEY_IV_SIZE];
uint8_t rsa_key_iv[KEY_IV_SIZE];
size_t rsa_key_length;
uint32_t nonce;
};
@@ -106,10 +108,10 @@ struct Test_PST_Report {
};
struct EntitledContentKeyData {
uint8_t entitlement_key_id[wvcdm::KEY_SIZE];
uint8_t content_key_id[wvcdm::KEY_SIZE];
uint8_t content_key_data_iv[wvcdm::KEY_SIZE];
uint8_t content_key_data[wvcdm::KEY_SIZE];
uint8_t entitlement_key_id[KEY_SIZE];
uint8_t content_key_id[KEY_SIZE];
uint8_t content_key_data_iv[KEY_SIZE];
uint8_t content_key_data[KEY_SIZE];
};
// Increment counter for AES-CTR. The CENC spec specifies we increment only
@@ -332,9 +334,14 @@ class Session {
// Verify the values in the PST report. The signature should have been
// verified in GenerateReport, above.
void VerifyPST(const Test_PST_Report& report);
// Generate and Verify the Usage Report. If any time is greater than 10
// minutes, it is assumed to be an absolute time, and time_since will be
// computed relative to now.
// Verify the Usage Report. If any time is greater than 10 minutes, it is
// assumed to be an absolute time, and time_since will be computed relative to
// now.
void VerifyReport(Test_PST_Report report,
int64_t time_license_received = 0,
int64_t time_first_decrypt = 0,
int64_t time_last_decrypt = 0);
// Same as above, but generates the report with the given status.
void GenerateVerifyReport(const std::string& pst,
OEMCrypto_Usage_Entry_Status status,
int64_t time_license_received = 0,
@@ -373,9 +380,6 @@ class Session {
// The size of the encrypted message.
size_t message_size() { return message_size_; }
// If this session has an entitlement license.
bool has_entitlement_license() const { return has_entitlement_license_; }
private:
// Generate mac and enc keys give the master key.
void DeriveKeys(const uint8_t* master_key,
@@ -405,7 +409,6 @@ class Session {
vector<uint8_t> encrypted_usage_entry_;
uint32_t usage_entry_number_;
string pst_;
bool has_entitlement_license_;
// Clear Entitlement key data. This is the backing data for
// |entitled_key_array_|.

View File

@@ -5,7 +5,6 @@
#include <openssl/rand.h>
#include "oec_session_util.h"
#include "OEMCryptoCENC.h"
#include "test_keybox.h"
#include "test_rsa_key.h"

View File

@@ -1,4 +1,6 @@
// Copyright 2013 Google Inc. All Rights Reserved.
// 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.
//
// OEMCrypto unit tests
//
@@ -29,14 +31,15 @@
#include "log.h"
#include "oec_device_features.h"
#include "oec_session_util.h"
#include "oemcrypto_key_mock.h"
#include "oemcrypto_session_tests_helper.h"
#include "properties.h"
#include "oemcrypto_types.h"
#include "string_conversions.h"
#include "test_keybox.h"
#include "test_rsa_key.h"
#include "wv_cdm_constants.h"
#include "wv_keybox.h"
#ifdef CDM_TESTS
#include "properties.h"
#endif
using ::testing::Bool;
using ::testing::Combine;
@@ -74,7 +77,9 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil {
virtual void SetUp() {
::testing::Test::SetUp();
#ifdef CDM_TESTS
wvcdm::Properties::Init();
#endif
wvcdm::g_cutoff = wvcdm::LOG_INFO;
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
@@ -769,7 +774,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithNonce) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
}
@@ -786,7 +791,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeySeveralNonce) {
s.GenerateNonce(); // three.
s.GenerateNonce(); // four.
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, first_nonce));
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, first_nonce));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
}
@@ -959,7 +964,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange4) {
vector<uint8_t> bad_buffer(
s.encrypted_license().keys[1].key_data,
s.encrypted_license().keys[1].key_data + wvcdm::KEY_SIZE);
s.encrypted_license().keys[1].key_data + wvoec::KEY_SIZE);
s.key_array()[1].key_data = &bad_buffer[0];
OEMCryptoResult sts = OEMCrypto_LoadKeys(
@@ -1033,7 +1038,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadNonce) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0,
wvoec_mock::kControlNonceEnabled,
wvoec::kControlNonceEnabled,
42)); // bad nonce.
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
OEMCryptoResult sts = OEMCrypto_LoadKeys(
@@ -1051,7 +1056,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
uint32_t nonce = s.get_nonce();
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, nonce));
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, nonce));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
ASSERT_NO_FATAL_FAILURE(s.close());
@@ -1059,7 +1064,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0,
wvoec_mock::kControlNonceEnabled,
wvoec::kControlNonceEnabled,
nonce)); // same old nonce.
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
OEMCryptoResult sts = OEMCrypto_LoadKeys(
@@ -1071,6 +1076,57 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithRepeatNonce) {
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
// This tests that a nonce cannot be used in new session.
TEST_F(OEMCryptoSessionTests, LoadKeyNonceReopenSession) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
uint32_t nonce = s.get_nonce();
// Do not use the nonce now. Close session and use it after re-opening.
ASSERT_NO_FATAL_FAILURE(s.close());
// Actually, this isn't the same session. OEMCrypto opens a new session, but
// we are guarding against the possiblity that it re-uses the session data
// and might not clear out the nonce table correctly.
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, wvoec::kControlNonceEnabled,
nonce)); // same old nonce
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
OEMCryptoResult sts = OEMCrypto_LoadKeys(
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
s.signature().size(), s.encrypted_license().mac_key_iv,
s.encrypted_license().mac_keys, s.num_keys(), s.key_array(), NULL, 0,
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
// This tests that a nonce cannot be used in wrong session.
TEST_F(OEMCryptoSessionTests, LoadKeyNonceWrongSession) {
Session s1;
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
uint32_t nonce = s1.get_nonce();
// Do not use the nonce. Also, leave the session open. We want to make sure
// that s and s1 do NOT share a nonce table. This is different from the
// LoadKeyNonceReopenSession in that we do not close s1.
Session s2;
ASSERT_NO_FATAL_FAILURE(s2.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
ASSERT_NO_FATAL_FAILURE(s2.FillSimpleMessage(0, wvoec::kControlNonceEnabled,
nonce)); // nonce from session s1
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
OEMCryptoResult sts = OEMCrypto_LoadKeys(
s2.session_id(), s2.message_ptr(), s2.message_size(), &s2.signature()[0],
s2.signature().size(), s2.encrypted_license().mac_key_iv,
s2.encrypted_license().mac_keys, s2.num_keys(), s2.key_array(), NULL, 0,
NULL, OEMCrypto_ContentLicense);
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
TEST_F(OEMCryptoSessionTests, LoadKeyWithBadVerification) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
@@ -1186,7 +1242,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyNoKeyWithNonce) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
int kNoKeys = 0;
ASSERT_NE(
@@ -1202,7 +1258,7 @@ TEST_F(OEMCryptoSessionTests, QueryKeyControl) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, wvoec_mock::kControlNonceEnabled, s.get_nonce()));
s.FillSimpleMessage(0, wvoec::kControlNonceEnabled, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
// Note: successful cases are tested in VerifyTestKeys.
@@ -1229,7 +1285,7 @@ TEST_F(OEMCryptoSessionTests, AntiRollbackHardwareRequired) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlRequireAntiRollbackHardware, 0));
0, wvoec::kControlRequireAntiRollbackHardware, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
OEMCryptoResult sts = OEMCrypto_LoadKeys(
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
@@ -1251,7 +1307,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, patch_level << wvoec_mock::kControlSecurityPatchLevelShift, 0));
0, patch_level << wvoec::kControlSecurityPatchLevelShift, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_EQ(
OEMCrypto_SUCCESS,
@@ -1267,7 +1323,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, (patch_level + 1) << wvoec_mock::kControlSecurityPatchLevelShift,
0, (patch_level + 1) << wvoec::kControlSecurityPatchLevelShift,
0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_EQ(
@@ -1284,7 +1340,7 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, (patch_level - 1) << wvoec_mock::kControlSecurityPatchLevelShift,
0, (patch_level - 1) << wvoec::kControlSecurityPatchLevelShift,
0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_EQ(
@@ -1326,8 +1382,8 @@ class SessionTestDecryptWithHDCP : public OEMCryptoSessionTests,
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0,
(version << wvoec_mock::kControlHDCPVersionShift) |
wvoec_mock::kControlObserveHDCP | wvoec_mock::kControlHDCPRequired,
(version << wvoec::kControlHDCPVersionShift) |
wvoec::kControlObserveHDCP | wvoec::kControlHDCPRequired,
0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
@@ -1371,14 +1427,14 @@ TEST_P(SessionTestRefreshKeyTest, RefreshWithNonce) {
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()));
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
s.GenerateNonce();
// License renewal message is signed by client and verified by the server.
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(num_keys_,
wvoec_mock::kControlNonceEnabled,
wvoec::kControlNonceEnabled,
s.get_nonce(), OEMCrypto_SUCCESS));
}
@@ -1401,14 +1457,14 @@ TEST_P(SessionTestRefreshKeyTest, RefreshOldNonceAPI11) {
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
uint32_t nonce = s.get_nonce();
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(kDuration, wvoec_mock::kControlNonceEnabled, nonce));
s.FillSimpleMessage(kDuration, wvoec::kControlNonceEnabled, nonce));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
// License renewal message is signed by client and verified by the server.
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
// Tryinng to reuse the same nonce.
ASSERT_NO_FATAL_FAILURE(
s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce,
s.RefreshTestKeys(num_keys_, wvoec::kControlNonceEnabled, nonce,
OEMCrypto_ERROR_INVALID_NONCE));
}
@@ -1417,7 +1473,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshBadNonceAPI11) {
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()));
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
s.GenerateNonce();
@@ -1425,7 +1481,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshBadNonceAPI11) {
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
uint32_t nonce = s.get_nonce() ^ 42;
ASSERT_NO_FATAL_FAILURE(
s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce,
s.RefreshTestKeys(num_keys_, wvoec::kControlNonceEnabled, nonce,
OEMCrypto_ERROR_INVALID_NONCE));
}
@@ -1435,7 +1491,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshLargeBuffer) {
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()));
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys("", new_mac_keys_));
s.GenerateNonce();
@@ -1443,7 +1499,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshLargeBuffer) {
// This uses a large buffer for the renewal message.
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature(kMaxMessageSize));
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(num_keys_,
wvoec_mock::kControlNonceEnabled,
wvoec::kControlNonceEnabled,
s.get_nonce(), OEMCrypto_SUCCESS));
}
@@ -1455,7 +1511,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshWithNoSelectKey) {
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()));
kDuration, wvoec::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
@@ -1469,7 +1525,7 @@ TEST_P(SessionTestRefreshKeyTest, RefreshWithNoSelectKey) {
// 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()));
num_keys_, wvoec::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_];
@@ -2077,7 +2133,7 @@ TEST_F(OEMCryptoSessionTests, DecryptSecureToClear) {
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
kDuration,
wvoec_mock::kControlObserveDataPath | wvoec_mock::kControlDataPathSecure,
wvoec::kControlObserveDataPath | wvoec::kControlDataPathSecure,
0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
@@ -2090,7 +2146,7 @@ TEST_F(OEMCryptoSessionTests, DecryptNoAnalogToClearAPI13) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
kDuration, wvoec_mock::kControlDisableAnalogOutput, 0));
kDuration, wvoec::kControlDisableAnalogOutput, 0));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
ASSERT_NO_FATAL_FAILURE(
@@ -2102,7 +2158,7 @@ TEST_F(OEMCryptoSessionTests, KeyDuration) {
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()));
kDuration, wvoec::kControlNonceEnabled, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR(true, OEMCrypto_SUCCESS));
@@ -3766,22 +3822,22 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
ASSERT_NO_FATAL_FAILURE(
session_.FillSimpleMessage(duration, control, nonce, pst));
session_.license().keys[0].control.control_bits |=
htonl(wvoec_mock::kControlAllowEncrypt);
htonl(wvoec::kControlAllowEncrypt);
session_.license().keys[1].control.control_bits |=
htonl(wvoec_mock::kControlAllowDecrypt);
htonl(wvoec::kControlAllowDecrypt);
session_.license().keys[2].control.control_bits |=
htonl(wvoec_mock::kControlAllowSign);
htonl(wvoec::kControlAllowSign);
session_.license().keys[3].control.control_bits |=
htonl(wvoec_mock::kControlAllowVerify);
htonl(wvoec::kControlAllowVerify);
session_.license().keys[2].key_data_length = wvcdm::MAC_KEY_SIZE;
session_.license().keys[3].key_data_length = wvcdm::MAC_KEY_SIZE;
session_.license().keys[2].key_data_length = wvoec::MAC_KEY_SIZE;
session_.license().keys[3].key_data_length = wvoec::MAC_KEY_SIZE;
clear_buffer_.assign(buffer_size_, 0);
for (size_t i = 0; i < clear_buffer_.size(); i++) {
clear_buffer_[i] = 1 + i % 250;
}
for (size_t i = 0; i < wvcdm::KEY_IV_SIZE; i++) {
for (size_t i = 0; i < wvoec::KEY_IV_SIZE; i++) {
iv_[i] = i;
}
}
@@ -3797,8 +3853,8 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
ASSERT_EQ(0,
AES_set_encrypt_key(session_.license().keys[key_index].key_data,
AES_BLOCK_SIZE * 8, &aes_key));
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
memcpy(iv_buffer, iv_, wvcdm::KEY_IV_SIZE);
uint8_t iv_buffer[wvoec::KEY_IV_SIZE];
memcpy(iv_buffer, iv_, wvoec::KEY_IV_SIZE);
out_buffer->resize(in_buffer.size());
ASSERT_GT(in_buffer.size(), 0u);
ASSERT_EQ(0u, in_buffer.size() % AES_BLOCK_SIZE);
@@ -3812,7 +3868,7 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
unsigned int md_len = SHA256_DIGEST_LENGTH;
signature->resize(SHA256_DIGEST_LENGTH);
HMAC(EVP_sha256(), session_.license().keys[key_index].key_data,
wvcdm::MAC_KEY_SIZE, &in_buffer[0], in_buffer.size(),
wvoec::MAC_KEY_SIZE, &in_buffer[0], in_buffer.size(),
signature->data(), &md_len);
}
@@ -3896,7 +3952,7 @@ class GenericCryptoTest : public OEMCryptoSessionTests {
size_t buffer_size_;
vector<uint8_t> clear_buffer_;
vector<uint8_t> encrypted_buffer_;
uint8_t iv_[wvcdm::KEY_IV_SIZE];
uint8_t iv_[wvoec::KEY_IV_SIZE];
Session session_;
};
@@ -3991,7 +4047,7 @@ TEST_F(GenericCryptoTest, GenericKeyDecryptSameBufferAPI12) {
TEST_F(GenericCryptoTest, GenericSecureToClear) {
session_.license().keys[1].control.control_bits |= htonl(
wvoec_mock::kControlObserveDataPath | wvoec_mock::kControlDataPathSecure);
wvoec::kControlObserveDataPath | wvoec::kControlDataPathSecure);
EncryptAndLoadKeys();
unsigned int key_index = 1;
vector<uint8_t> encrypted;
@@ -4313,7 +4369,7 @@ class GenericCryptoKeyIdLengthTest : public GenericCryptoTest {
const uint32_t kNoNonce = 0;
session_.set_num_keys(5);
ASSERT_NO_FATAL_FAILURE(session_.FillSimpleMessage(
kDuration, wvoec_mock::kControlAllowDecrypt, kNoNonce));
kDuration, wvoec::kControlAllowDecrypt, kNoNonce));
SetUniformKeyIdLength(16); // Start with all key ids being 16 bytes.
// But, we are testing that the key ids do not have to have the same length.
session_.SetKeyId(0, "123456789012"); // 12 bytes (common key id length).
@@ -4404,7 +4460,7 @@ class UsageTableTest : public GenericCryptoTest {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
@@ -4451,7 +4507,7 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -4475,13 +4531,37 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) {
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
}
TEST_P(UsageTableTestWithMAC, OnlineLicenseUnused) {
std::string pst = "my_pst";
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
// No decrypt. We do not use this license.
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kUnused));
// Flag the entry as inactive.
ASSERT_NO_FATAL_FAILURE(s.DeactivateUsageEntry(pst));
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
// It should report as inactive.
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kInactiveUnused));
// Decrypt should fail.
ASSERT_NO_FATAL_FAILURE(
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
}
TEST_P(UsageTableTestWithMAC, ForbidReportWithNoUpdate) {
std::string pst = "my_pst";
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -4511,7 +4591,7 @@ TEST_P(UsageTableTestWithMAC, OnlineLicenseWithRefresh) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -4524,7 +4604,7 @@ TEST_P(UsageTableTestWithMAC, OnlineLicenseWithRefresh) {
size_t kAllKeys = 1;
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(
kAllKeys,
wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(
@@ -4540,7 +4620,7 @@ TEST_F(UsageTableTest, RepeatOnlineLicense) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -4571,7 +4651,7 @@ TEST_F(UsageTableTest, OnlineEmptyPST) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -4591,7 +4671,7 @@ TEST_F(UsageTableTest, OnlineMissingEntry) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
// ENTRY NOT CREATED: ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -4610,7 +4690,7 @@ TEST_F(UsageTableTest, TwoHundredEntries) {
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
std::string pst1 = "pst saved";
ASSERT_NO_FATAL_FAILURE(s1.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s1.get_nonce(), pst1));
ASSERT_NO_FATAL_FAILURE(s1.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s1.CreateNewUsageEntry());
@@ -4620,7 +4700,8 @@ TEST_F(UsageTableTest, TwoHundredEntries) {
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s1.close());
const size_t ENTRY_COUNT = 200; // API says should hold at least 200 entries.
// API says should hold at least 200 entries. Subtract one for s1's entry.
const size_t ENTRY_COUNT = 200 - 1;
vector<Session> sessions(ENTRY_COUNT);
for (size_t i = 0; i < ENTRY_COUNT; i++) {
ASSERT_NO_FATAL_FAILURE(sessions[i].open());
@@ -4630,7 +4711,7 @@ TEST_F(UsageTableTest, TwoHundredEntries) {
char c2 = 'A' + (i%26);
pst = pst + c1 + c2;
ASSERT_NO_FATAL_FAILURE(sessions[i].FillSimpleMessage(
0, wvoec_mock::kControlNonceOrEntry, sessions[i].get_nonce(), pst));
0, wvoec::kControlNonceOrEntry, sessions[i].get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(sessions[i].EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(sessions[i].CreateNewUsageEntry());
ASSERT_EQ(sessions[i].usage_entry_number(), i + 1);
@@ -4667,7 +4748,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoEncrypt) {
std::string pst = "A PST";
uint32_t nonce = session_.get_nonce();
MakeFourKeys(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
nonce, pst);
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
@@ -4704,7 +4785,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoDecrypt) {
std::string pst = "my_pst";
uint32_t nonce = session_.get_nonce();
MakeFourKeys(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
nonce, pst);
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
@@ -4741,7 +4822,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoSign) {
std::string pst = "my_pst";
uint32_t nonce = session_.get_nonce();
MakeFourKeys(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
nonce, pst);
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
@@ -4789,7 +4870,7 @@ TEST_P(UsageTableTestWithMAC, GenericCryptoVerify) {
std::string pst = "my_pst";
uint32_t nonce = session_.get_nonce();
MakeFourKeys(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
nonce, pst);
ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
@@ -4832,7 +4913,7 @@ TEST_P(UsageTableTestWithMAC, OfflineLicenseRefresh) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
@@ -4843,7 +4924,7 @@ TEST_P(UsageTableTestWithMAC, OfflineLicenseRefresh) {
ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature());
size_t kAllKeys = 1;
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(
kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
kAllKeys, wvoec::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(
@@ -4896,7 +4977,7 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineLicenseWithRefresh) {
decrypt_time)); // last decrypt
size_t kAllKeys = 1;
ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys(
kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
kAllKeys, wvoec::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kActive,
@@ -4941,7 +5022,7 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) {
ASSERT_NO_FATAL_FAILURE(s2.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
ASSERT_NO_FATAL_FAILURE(s2.FillSimpleMessage(
0, wvoec_mock::kControlNonceOrEntry, s2.get_nonce(), pst));
0, wvoec::kControlNonceOrEntry, s2.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s2.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s));
uint8_t* pst_ptr = s2.encrypted_license().pst;
@@ -4975,7 +5056,7 @@ TEST_P(UsageTableTestWithMAC, OfflineBadNonce) {
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, wvoec_mock::kControlNonceOrEntry, 42, pst));
s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, 42, pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
uint8_t* pst_ptr = s.encrypted_license().pst;
OEMCryptoResult sts = OEMCrypto_LoadKeys(
@@ -4994,7 +5075,7 @@ TEST_P(UsageTableTestWithMAC, OfflineEmptyPST) {
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
ASSERT_NO_FATAL_FAILURE(
s.FillSimpleMessage(0, wvoec_mock::kControlNonceOrEntry, s.get_nonce()));
s.FillSimpleMessage(0, wvoec::kControlNonceOrEntry, s.get_nonce()));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
OEMCryptoResult sts = OEMCrypto_LoadKeys(
s.session_id(), s.message_ptr(), s.message_size(), &s.signature()[0],
@@ -5069,6 +5150,49 @@ TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicense) {
EXPECT_EQ(kInactiveUsed, s3.pst_report().status());
}
TEST_P(UsageTableTestWithMAC, DeactivateOfflineLicenseUnused) {
std::string pst = "my_pst";
Session s1;
ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s1, pst));
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
ASSERT_NO_FATAL_FAILURE(
s1.LoadTestKeys(pst, new_mac_keys_)); // Reload the license
// No Decrypt. This license is unused.
ASSERT_NO_FATAL_FAILURE(s1.DeactivateUsageEntry(pst)); // Then deactivate.
// After deactivate, should not be able to decrypt.
ASSERT_NO_FATAL_FAILURE(
s1.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s1.GenerateVerifyReport(pst, kInactiveUnused));
ASSERT_NO_FATAL_FAILURE(s1.close());
Session s2;
ASSERT_NO_FATAL_FAILURE(s2.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s2));
ASSERT_NO_FATAL_FAILURE(s2.LoadUsageEntry(s1));
// Offline license can not be reused if it has been deactivated.
uint8_t* pst_ptr = s1.encrypted_license().pst;
EXPECT_NE(
OEMCrypto_SUCCESS,
OEMCrypto_LoadKeys(s2.session_id(), s1.message_ptr(), s1.message_size(),
&s1.signature()[0], s1.signature().size(),
s1.encrypted_license().mac_key_iv,
s1.encrypted_license().mac_keys, s1.num_keys(),
s1.key_array(), pst_ptr, pst.length(), NULL,
OEMCrypto_ContentLicense));
s2.close();
// But we can still generate a report.
Session s3;
ASSERT_NO_FATAL_FAILURE(s3.open());
ASSERT_NO_FATAL_FAILURE(s3.LoadUsageEntry(s1));
ASSERT_NO_FATAL_FAILURE(s3.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s3.GenerateReport(pst, OEMCrypto_SUCCESS, &s1));
EXPECT_EQ(kInactiveUnused, s3.pst_report().status());
}
TEST_P(UsageTableTestWithMAC, BadRange) {
std::string pst = "my_pst";
Session s;
@@ -5076,7 +5200,7 @@ TEST_P(UsageTableTestWithMAC, BadRange) {
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(session_.CreateNewUsageEntry());
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
uint8_t* pst_ptr = s.license().pst; // Bad: not in encrypted_license.
ASSERT_NE(
@@ -5095,7 +5219,7 @@ TEST_F(UsageTableTest, UpdateFailsWithNullPtr) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -5125,7 +5249,7 @@ class UsageTableDefragTest : public UsageTableTest {
char c2 = 'A' + (index % 26);
pst = pst + c1 + c2;
ASSERT_NO_FATAL_FAILURE(s->FillSimpleMessage(
0, wvoec_mock::kControlNonceOrEntry, s->get_nonce(), pst));
0, wvoec::kControlNonceOrEntry, s->get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s->EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s->CreateNewUsageEntry());
ASSERT_EQ(s->usage_entry_number(), index);
@@ -5433,7 +5557,7 @@ TEST_F(UsageTableTest, GenerateReportWrongPST) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst));
0, wvoec::kControlNonceOrEntry, s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
@@ -5530,7 +5654,7 @@ TEST_F(UsageTableTest, VerifyUsageTimes) {
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
0, wvoec::kControlNonceEnabled | wvoec::kControlNonceRequired,
s.get_nonce(), pst));
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.CreateNewUsageEntry());
@@ -5614,6 +5738,86 @@ TEST_F(UsageTableTest, VerifyUsageTimes) {
s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
}
// NOTE: This test needs root access since clock_settime messes with the system
// time in order to verify that OEMCrypto protects against rollbacks in usage
// entries. Therefore, this test is filtered if not run as root.
// We don't test roll-forward protection or instances where the user rolls back
// the time to the last decrypt call since this requires hardware-secure clocks
// to guarantee.
TEST_F(UsageTableTest, TimeRollbackPrevention) {
std::string pst = "my_pst";
Session s1;
cout << "This test temporarily rolls back the system time in order to verify "
<< "that the usage report accounts for the change. It then rolls "
<< "the time back forward to the absolute time." << endl;
// We use clock_gettime(CLOCK_REALTIME, ...) over time(...) so we can easily
// set the time using clock_settime.
timespec current_time;
ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &current_time));
time_t loaded = current_time.tv_sec;
ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s1, pst));
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
ASSERT_NO_FATAL_FAILURE(s1.LoadTestKeys(pst, new_mac_keys_));
ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &current_time));
time_t first_decrypt = current_time.tv_sec;
// Monotonic clock can't be changed. We use this since system clock will be
// unreliable.
ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &current_time));
time_t first_decrypt_monotonic = current_time.tv_sec;
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s1.close());
// Imitate playback.
sleep(kLongDuration * 2);
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
ASSERT_NO_FATAL_FAILURE(s1.LoadTestKeys(pst, new_mac_keys_));
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s1.close());
ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &current_time));
// Rollback the wall clock time.
cout << "Rolling the system time back..." << endl;
timeval current_time_of_day = {};
current_time_of_day.tv_sec = current_time.tv_sec - kLongDuration * 10;
ASSERT_EQ(0, settimeofday(&current_time_of_day, NULL));
// Try to playback again.
ASSERT_NO_FATAL_FAILURE(s1.open());
ASSERT_NO_FATAL_FAILURE(s1.ReloadUsageEntry());
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s1));
ASSERT_NO_FATAL_FAILURE(s1.LoadTestKeys(pst, new_mac_keys_));
ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &current_time));
time_t third_decrypt = current_time.tv_sec;
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
ASSERT_NO_FATAL_FAILURE(s1.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s1.GenerateReport(pst));
Test_PST_Report expected(pst, kActive);
// Restore wall clock to its original position to verify that OEMCrypto does
// not report negative times.
ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &current_time));
current_time_of_day.tv_sec =
first_decrypt + current_time.tv_sec - first_decrypt_monotonic;
cout << "Rolling the system time forward to the absolute time..." << endl;
ASSERT_EQ(0, settimeofday(&current_time_of_day, NULL));
// Need to update time created since the verification checks the time of PST
// report creation.
expected.time_created = current_time_of_day.tv_sec;
ASSERT_NO_FATAL_FAILURE(
s1.VerifyReport(expected, loaded, first_decrypt,
first_decrypt + third_decrypt - first_decrypt_monotonic));
ASSERT_NO_FATAL_FAILURE(s1.close());
}
// This is a special case where a group of assets can be licensed with a master
// key. In order for this to work, a single session must first load a device
// specific license, and then a shared content license. This shared license is
@@ -5640,7 +5844,7 @@ TEST_F(UsageTableTest, LoadSharedLicense) {
s.license().keys[i].key_id_length);
s.license().keys[i].control.nonce = 0;
s.license().keys[i].control.control_bits =
htonl(wvoec_mock::kSharedLicense);
htonl(wvoec::kSharedLicense);
}
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, false));
@@ -5669,7 +5873,7 @@ TEST_F(UsageTableTest, LoadSharedLicenseWithNoMaster) {
s.license().keys[i].key_id_length);
s.license().keys[i].control.nonce = 0;
s.license().keys[i].control.control_bits =
htonl(wvoec_mock::kSharedLicense);
htonl(wvoec::kSharedLicense);
}
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
uint8_t* pst_ptr = s.encrypted_license().pst;

View File

@@ -1,4 +1,6 @@
// Copyright 2013 Google Inc. All Rights Reserved.
// 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.
//
// OEMCrypto unit tests - extra tests required for Android platform.
//
@@ -109,7 +111,7 @@ TEST_F(OEMCryptoAndroidMNCTest, LoadTestKeybox) {
if (OEMCrypto_Keybox == OEMCrypto_GetProvisioningMethod()) {
OEMCryptoResult status = OEMCrypto_LoadTestKeybox(
reinterpret_cast<const uint8_t*>(&kTestKeybox),
sizeof(kTestKeybox)));
sizeof(kTestKeybox));
// OEMCrypto may return success or not implemented.
if (status == OEMCrypto_SUCCESS) {
LOGV("OEMCrypto_LoadTestKeybox is implemented.");

View File

@@ -4,7 +4,9 @@
#include "OEMCryptoCENC.h"
#include "log.h"
#include "oec_device_features.h"
#ifdef CDM_TESTS
#include "properties.h"
#endif
static void acknowledge_cast() {
std::cout
@@ -15,7 +17,9 @@ static void acknowledge_cast() {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
#ifdef CDM_TESTS
wvcdm::Properties::Init();
#endif
wvcdm::g_cutoff = wvcdm::LOG_INFO;
bool is_cast_receiver = false;
bool force_load_test_keybox = false;

View File

@@ -0,0 +1,40 @@
# This is a gyp file for building the OEMCrypto unit tests with the reference
# code from the stand-alone source code.
{
'variables': {
# Override the variables below for the location of various gyp files.
# Alternatively, set the environment variable CDM_DIR to point to a recent
# version of the source CDM.
'boringssl_dependency%': '<!(echo $CDM_DIR)/third_party/boringssl/boringssl.gyp:legacy_ssl',
'gtest_dependency%': '<!(echo $CDM_DIR)/third_party/gmock.gyp:gtest',
'gmock_dependency%': '<!(echo $CDM_DIR)/third_party/gmock.gyp:gmock',
'oemcrypto_dir%': '..',
'util_dir%': '../../util',
'platform_specific_dir%': '<!(echo $CDM_DIR)/linux/src',
},
'targets': [
{
'target_name': 'oemcrypto_unittests',
'type': 'executable',
'sources': [
'oemcrypto_test_main.cpp',
'<(platform_specific_dir)/file_store.cpp',
'<(platform_specific_dir)/lock.cpp',
'<(platform_specific_dir)/log.cpp',
'<(util_dir)/src/string_conversions.cpp',
],
'includes': [
'oemcrypto_unittests.gypi',
'../ref/oec_ref.gypi',
],
'libraries': [
'-lpthread', # gtest
],
'dependencies': [
'<(boringssl_dependency)',
'<(gtest_dependency)',
'<(gmock_dependency)',
],
},
],
}

View File

@@ -0,0 +1,30 @@
# 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 this in any custom unit test targets.
# Does not include the test runner main.
{
'sources': [
'oec_device_features.cpp',
'oec_session_util.cpp',
'oemcrypto_session_tests_helper.cpp',
'oemcrypto_test.cpp',
'../../test/auth/test_keybox.cpp',
'../../test/auth/test_rsa_key.cpp',
'../../test/auth/test_oem_cert.cpp',
'../../test/auth/test_service_cert.cpp',
],
'include_dirs': [
'<(util_dir)/include',
'<(oemcrypto_dir)/include',
'<(oemcrypto_dir)/test',
'../../test/auth',
],
'defines': [
'OEMCRYPTO_TESTS',
],
'dependencies': [
'<(boringssl_dependency)',
],
}