Merge OEMCrypto changes from CDM to android repository

This is a merge of the following CLs:

Style clean up in oemcrypto/mock
https://widevine-internal-review.googlesource.com/#/c/10660

Split off default keybox.
https://widevine-internal-review.googlesource.com/#/c/10661/

Split off several properties from CryptoEngine.
https://widevine-internal-review.googlesource.com/#/c/10662/

Split off Keybox installation.
https://widevine-internal-review.googlesource.com/#/c/10680/

Wii-U build compatibility fixes.
https://widevine-internal-review.googlesource.com/#/c/10720/

Fix style issues in oemcrypto_logging_test.
https://widevine-internal-review.googlesource.com/#/c/10824/

Correct OEMCrypto error codes in the mock.
https://widevine-internal-review.googlesource.com/#/c/10821/

Enable logging during OEMCrypto unit tests.
https://widevine-internal-review.googlesource.com/#/c/10833/

Wait to create usage table path until needed.
https://widevine-internal-review.googlesource.com/#/c/10831/

Allow keybox installation to be unimplemented.
https://widevine-internal-review.googlesource.com/#/c/10850/

Minor clean up in the OEMCrypto header.
https://widevine-internal-review.googlesource.com/#/c/10921/

Add usage table device property to the mock oemcrypto
https://widevine-internal-review.googlesource.com/#/c/11092/

Change-Id: I02a818a620bcd4bd2291f1b3c0ac9308ae444319
This commit is contained in:
Fred Gylys-Colwell
2015-02-27 15:13:52 -08:00
parent 723d67c88f
commit 87ea4f6ad4
18 changed files with 293 additions and 312 deletions

View File

@@ -0,0 +1,36 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// Mock implementation of OEMCrypto APIs
//
#include "oemcrypto_engine_mock.h"
namespace wvoec_mock {
// If local_display() returns true, we pretend we are using a built-in display,
// instead of HDMI or WiFi output.
bool CryptoEngine::local_display() {
return false;
}
// A closed platform is permitted to use clear buffers.
bool CryptoEngine::closed_platform() {
return false;
}
// Returns the HDCP version currently in use.
OEMCrypto_HDCP_Capability CryptoEngine::current_hdcp_capability() {
return local_display() ? 0xFF : 0x01;
}
// Returns the max HDCP version supported.
OEMCrypto_HDCP_Capability CryptoEngine::maximum_hdcp_capability() {
return 0x02;
}
// Returns true if the client supports persistent storage of
// offline usage table information.
bool CryptoEngine::supports_storage() {
return true;
}
} // namespace wvoec_mock

View File

@@ -343,14 +343,15 @@ bool SessionContext::CheckNonceOrEntry(const KeyControlBlock& key_control_block,
const std::vector<uint8_t>& pst) {
switch (key_control_block.control_bits() & kControlReplayMask) {
case kControlNonceRequired: // Online license. Nonce always required.
if (!CheckNonce(key_control_block.nonce())) return false;
if (pst.size() == 0) {
LOGE("KCB: PST null for kControlNonceRequired.");
return false;
}
if (!(key_control_block.control_bits() & kControlNonceEnabled)) {
LOGE("KCB: Server provided Nonce_Required but Nonce_Enabled = 0.");
// Server error. Continue, and assume nonce required.
}
if (!CheckNonce(key_control_block.nonce())) return false;
if (!usage_entry_) {
if (ce_->usage_table()->FindEntry(pst)) {
LOGE("KCB: Cannot create duplicate entries in usage table.");
@@ -362,6 +363,7 @@ bool SessionContext::CheckNonceOrEntry(const KeyControlBlock& key_control_block,
case kControlNonceOrEntry:
if (key_control_block.control_bits() & kControlNonceEnabled) {
LOGE("KCB: Server provided NonceOrEntry but Nonce_Enabled = 1.");
// Server error. Continue, and assume nonce required.
}
if (pst.size() == 0) {
LOGE("KCB: PST null for kControlNonceOrEntry.");
@@ -773,8 +775,10 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (control.control_bits() & kControlDataPathSecure) {
LOGE("[Generic_Decrypt(): control bit says secure path only.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
if (!ce_->closed_platform()) {
LOGE("[Generic_Decrypt(): control bit says secure path only.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if (control.duration() > 0) {
if (control.duration() < CurrentTimer()) {
@@ -966,17 +970,9 @@ bool SessionContext::IsUsageEntryValid() {
void SessionContext::ReleaseUsageEntry() { usage_entry_ = NULL; }
CryptoEngine::CryptoEngine() :
ce_state_(CE_INITIALIZED), current_session_(NULL) {
valid_ = true;
CryptoEngine::CryptoEngine()
: current_session_(NULL), usage_table_(new UsageTable(this)) {
ERR_load_crypto_strings();
// These are made up numbers, just for illustration.
current_hdcp_capability_ = 0x1;
maximum_hdcp_capability_ = 0x2;
// If local_display_ is true, we pretend we are using a built-in display,
// instead of HDMI or WiFi output.
local_display_ = false;
usage_table_ = new UsageTable(this);
}
CryptoEngine::~CryptoEngine() {
@@ -1061,7 +1057,7 @@ OEMCryptoResult SessionContext::DecryptCTR(
}
const KeyControlBlock& control = current_content_key()->control();
if (control.control_bits() & kControlDataPathSecure) {
if (buffer_type == kBufferTypeClear) {
if (!ce_->closed_platform() && buffer_type == kBufferTypeClear) {
LOGE("[DecryptCTR(): Secure key with insecure buffer]");
return OEMCrypto_ERROR_DECRYPT_FAILED;
}
@@ -1198,4 +1194,4 @@ void NonceTable::Flush() {
}
}
}; // namespace wvoec_mock
} // namespace wvoec_mock

View File

@@ -2,8 +2,8 @@
//
// Mock implementation of OEMCrypto APIs
//
#ifndef WVOEC_MOCK_OEMCRYPTO_ENGINE_MOCK_H_
#define WVOEC_MOCK_OEMCRYPTO_ENGINE_MOCK_H_
#ifndef OEMCRYPTO_ENGINE_MOCK_H_
#define OEMCRYPTO_ENGINE_MOCK_H_
#include <openssl/rsa.h>
#include <stdint.h>
@@ -220,26 +220,14 @@ class SessionContext {
};
class CryptoEngine {
private:
enum CryptoEngineState {
CE_ILLEGAL,
CE_INITIALIZED,
CE_HAS_KEYBOX,
CE_HAS_SESSIONS,
CE_ERROR
};
public:
CryptoEngine();
~CryptoEngine();
bool Initialized() { return (ce_state_ != CE_ILLEGAL); }
bool Initialized() { return true; }
void Terminate();
bool isValid() { return valid_; }
KeyboxError ValidateKeybox();
WvKeybox& keybox() { return keybox_; }
@@ -253,32 +241,24 @@ class CryptoEngine {
current_session_ = current;
}
OEMCrypto_HDCP_Capability current_hdcp_capability() const {
return local_display_ ? 0xFF : current_hdcp_capability_;
}
OEMCrypto_HDCP_Capability maximum_hdcp_capability() const {
return maximum_hdcp_capability_;
}
OEMCrypto_HDCP_Capability current_hdcp_capability();
OEMCrypto_HDCP_Capability maximum_hdcp_capability();
UsageTable* usage_table() { return usage_table_; }
bool local_display() { return local_display_; }
bool local_display();
bool closed_platform();
bool supports_storage();
private:
bool valid_;
CryptoEngineState ce_state_;
SessionContext* current_session_;
ActiveSessions sessions_;
WvKeybox keybox_;
wvcdm::Lock session_table_lock_;
OEMCrypto_HDCP_Capability current_hdcp_capability_;
OEMCrypto_HDCP_Capability maximum_hdcp_capability_;
bool local_display_;
UsageTable* usage_table_;
CORE_DISALLOW_COPY_AND_ASSIGN(CryptoEngine);
};
}; // namespace wvoec_eng
} // namespace wvoec_mock
#endif // WVOEC_MOCK_OEMCRYPTO_ENGINE_MOCK_H_
#endif // OEMCRYPTO_ENGINE_MOCK_H_

View File

@@ -107,4 +107,4 @@ void Key::UpdateDuration(const KeyControlBlock& control) {
control_.set_duration(control.duration());
}
}; // namespace wvoec_mock
} // namespace wvoec_mock

View File

@@ -72,6 +72,6 @@ class Key {
KeyControlBlock control_;
};
}; // namespace wvoec_eng
} // namespace wvoec_mock
#endif
#endif // OEMCRYPTO_KEY_MOCK_H_

View File

@@ -14,47 +14,8 @@
namespace wvoec_mock {
const WidevineKeybox kDefaultKeybox = {
// Sample keybox used for test vectors
{
// deviceID
0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x30, // TestKey01
0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
}, {
// key
0xfb, 0xda, 0x04, 0x89, 0xa1, 0x58, 0x16, 0x0e,
0xa4, 0x02, 0xe9, 0x29, 0xe3, 0xb6, 0x8f, 0x04,
}, {
// data
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x19,
0x07, 0xd9, 0xff, 0xde, 0x13, 0xaa, 0x95, 0xc1,
0x22, 0x67, 0x80, 0x53, 0x36, 0x21, 0x36, 0xbd,
0xf8, 0x40, 0x8f, 0x82, 0x76, 0xe4, 0xc2, 0xd8,
0x7e, 0xc5, 0x2b, 0x61, 0xaa, 0x1b, 0x9f, 0x64,
0x6e, 0x58, 0x73, 0x49, 0x30, 0xac, 0xeb, 0xe8,
0x99, 0xb3, 0xe4, 0x64, 0x18, 0x9a, 0x14, 0xa8,
0x72, 0x02, 0xfb, 0x02, 0x57, 0x4e, 0x70, 0x64,
0x0b, 0xd2, 0x2e, 0xf4, 0x4b, 0x2d, 0x7e, 0x39,
}, {
// magic
0x6b, 0x62, 0x6f, 0x78,
}, {
// Crc
0x0a, 0x7a, 0x2c, 0x35,
}
};
WvKeybox::WvKeybox() : valid_(false) {
Prepare();
}
bool WvKeybox::Prepare() {
InstallKeybox(reinterpret_cast<const uint8_t*>(&kDefaultKeybox),
sizeof(kDefaultKeybox));
valid_ = true;
return valid_;
WvKeybox::WvKeybox() {
valid_ = Prepare();
}
KeyboxError WvKeybox::Validate() {
@@ -101,7 +62,8 @@ bool WvKeybox::InstallKeybox(const uint8_t* buffer, size_t keyBoxLength) {
memcpy(key_data_, keybox->data_, sizeof(keybox->data_));
memcpy(magic_, keybox->magic_, sizeof(keybox->magic_));
memcpy(crc_, keybox->crc_, sizeof(keybox->crc_));
return true;
}
}; // namespace wvoec_mock
} // namespace wvoec_mock

View File

@@ -2,8 +2,8 @@
//
// Mock implementation of OEMCrypto APIs
//
#ifndef WVOEC_MOCK_OEMCRYPTO_KEYBOX_MOCK_H_
#define WVOEC_MOCK_OEMCRYPTO_KEYBOX_MOCK_H_
#ifndef OEMCRYPTO_KEYBOX_MOCK_H_
#define OEMCRYPTO_KEYBOX_MOCK_H_
#include "oemcrypto_key_mock.h"
@@ -41,6 +41,6 @@ class WvKeybox {
uint8_t crc_[4];
};
}; // namespace wvoec_eng
} // namespace wvoec_mock
#endif // WVOEC_MOCK_OEMCRYPTO_KEYBOX_MOCK_H_
#endif // OEMCRYPTO_KEYBOX_MOCK_H_

View File

@@ -0,0 +1,52 @@
// Copyright 2014 Google Inc. All Rights Reserved.
//
// Test keybox.
#include "oemcrypto_keybox_mock.h"
#include "wv_keybox.h"
namespace wvoec_mock {
namespace {
const WidevineKeybox kKeybox = {
// Sample keybox used for test vectors
{
// deviceID
0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x30, // TestKey01
0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
}, {
// key
0xfb, 0xda, 0x04, 0x89, 0xa1, 0x58, 0x16, 0x0e,
0xa4, 0x02, 0xe9, 0x29, 0xe3, 0xb6, 0x8f, 0x04,
}, {
// data
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x19,
0x07, 0xd9, 0xff, 0xde, 0x13, 0xaa, 0x95, 0xc1,
0x22, 0x67, 0x80, 0x53, 0x36, 0x21, 0x36, 0xbd,
0xf8, 0x40, 0x8f, 0x82, 0x76, 0xe4, 0xc2, 0xd8,
0x7e, 0xc5, 0x2b, 0x61, 0xaa, 0x1b, 0x9f, 0x64,
0x6e, 0x58, 0x73, 0x49, 0x30, 0xac, 0xeb, 0xe8,
0x99, 0xb3, 0xe4, 0x64, 0x18, 0x9a, 0x14, 0xa8,
0x72, 0x02, 0xfb, 0x02, 0x57, 0x4e, 0x70, 0x64,
0x0b, 0xd2, 0x2e, 0xf4, 0x4b, 0x2d, 0x7e, 0x39,
}, {
// magic
0x6b, 0x62, 0x6f, 0x78,
}, {
// Crc
0x0a, 0x7a, 0x2c, 0x35,
}
};
} // namespace
bool WvKeybox::Prepare() {
InstallKeybox(reinterpret_cast<const uint8_t*>(&kKeybox),
sizeof(kKeybox));
return true;
}
} // namespace wvoec_mock

View File

@@ -105,5 +105,4 @@ void dump_array_part(std::string array, size_t index,
LOGV(buffer.c_str());
}
} // namespace wvoec_mock
} // namespace wvoec_mock

View File

@@ -320,7 +320,7 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
// Later on, we use pst_length to verify the the pst is valid. This makes
// sure that we aren't given a null string but told it has postiive length.
if ((pst == NULL && pst_length > 0) || (pst != NULL && pst_length == 0)) {
if (pst == NULL && pst_length > 0) {
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_ONCTEXT - null pst.]");
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
@@ -346,8 +346,8 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
wvcdm::KEY_CONTROL_SIZE, false) ||
!RangeCheck(message, message_length, key_array[i].key_control_iv,
wvcdm::KEY_IV_SIZE, false)) {
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_SIGNATURE_FAILURE -range check %d]", i);
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range check %d]", i);
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
}
@@ -397,7 +397,7 @@ OEMCryptoResult OEMCrypto_RefreshKeys(
!RangeCheck(message, message_length, key_array[i].key_control_iv,
wvcdm::KEY_IV_SIZE, true)) {
LOGE("[OEMCrypto_RefreshKeys(): Range Check %d]", i);
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
}
@@ -721,7 +721,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
!RangeCheck(message, message_length, enc_rsa_key_iv, wvcdm::KEY_IV_SIZE,
true)) {
LOGE("[OEMCrypto_RewrapDeviceRSAKey(): - range check.]");
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Validate nonce
@@ -1175,11 +1175,14 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session,
extern "C"
bool OEMCrypto_SupportsUsageTable() {
bool supports_usage = crypto_engine->supports_storage();
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- bool OEMCrypto_SupportsUsageTable(); // returns true.\n");
LOGI("-- bool OEMCrypto_SupportsUsageTable(); // returns %s.\n",
(supports_usage ? "true" : "false"));
}
return true;
return supports_usage;
}
extern "C"
OEMCryptoResult OEMCrypto_UpdateUsageTable() {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
@@ -1264,7 +1267,7 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session,
}
if (!RangeCheck(message, message_length, pst, pst_length, false)) {
LOGE("[OEMCrypto_DeleteUsageEntry(): range check.]");
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
// Validate message signature
if (!session_ctx->ValidateMessage(message, message_length, signature,
@@ -1288,4 +1291,4 @@ OEMCryptoResult OEMCrypto_DeleteUsageTable() {
return OEMCrypto_SUCCESS;
}
}; // namespace wvoec_mock
} // namespace wvoec_mock

View File

@@ -153,12 +153,6 @@ UsageTable::UsageTable(CryptoEngine *ce) {
LOGE("UsageTable: Unable to get base path");
return;
}
if (!file.IsDirectory(path)) {
if (!file.CreateDirectory(path)) {
LOGE("UsageTable: could not create directory: %s", path.c_str());
return;
}
}
std::string filename = path + "UsageTable.dat";
if (!file.Exists(filename)) {
@@ -167,26 +161,28 @@ UsageTable::UsageTable(CryptoEngine *ce) {
}
return;
}
size_t file_size = file.FileSize(filename);
uint8_t encrypted_buffer[file_size];
uint8_t buffer[file_size];
StoredUsageTable *stored_table = reinterpret_cast<StoredUsageTable *>(buffer);
std::vector<uint8_t> encrypted_buffer(file_size);
std::vector<uint8_t> buffer(file_size);
StoredUsageTable *stored_table =
reinterpret_cast<StoredUsageTable *>(&buffer[0]);
StoredUsageTable *encrypted_table =
reinterpret_cast<StoredUsageTable *>(encrypted_buffer);
reinterpret_cast<StoredUsageTable *>(&encrypted_buffer[0]);
if (!file.Open(filename, wvcdm::File::kReadOnly | wvcdm::File::kBinary)) {
LOGE("UsageTable: File open failed: %s", path.c_str());
return;
}
file.Read(reinterpret_cast<char *>(encrypted_buffer), file_size);
file.Read(reinterpret_cast<char *>(&encrypted_buffer[0]), file_size);
file.Close();
// First, verify the signature of the usage table file.
std::vector<uint8_t> &key = ce_->keybox().device_key();
unsigned int sig_length = sizeof(stored_table->signature);
uint8_t computed_signature[SHA256_DIGEST_LENGTH];
unsigned int sig_length = sizeof(computed_signature);
if (!HMAC(EVP_sha256(), &key[0], key.size(),
encrypted_buffer + SHA256_DIGEST_LENGTH,
&encrypted_buffer[SHA256_DIGEST_LENGTH],
file_size - SHA256_DIGEST_LENGTH, computed_signature,
&sig_length)) {
LOGE("UsageTable: Could not recreate signature.");
@@ -195,7 +191,7 @@ UsageTable::UsageTable(CryptoEngine *ce) {
}
if (memcmp(encrypted_table->signature, computed_signature, sig_length)) {
LOGE("UsageTable: Invalid signature given: %s",
wvcdm::HexEncode(encrypted_buffer, sig_length).c_str());
wvcdm::HexEncode(&encrypted_buffer[0], sig_length).c_str());
LOGE("UsageTable: Invalid signature computed: %s",
wvcdm::HexEncode(computed_signature, sig_length).c_str());
table_.clear();
@@ -203,13 +199,12 @@ UsageTable::UsageTable(CryptoEngine *ce) {
}
// Next, decrypt the table.
memset(buffer, 0, file_size);
uint8_t iv_buffer[wvcdm::KEY_IV_SIZE];
memcpy(iv_buffer, encrypted_table->iv, wvcdm::KEY_IV_SIZE);
AES_KEY aes_key;
AES_set_decrypt_key(&key[0], 128, &aes_key);
AES_cbc_encrypt(encrypted_buffer + SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE,
buffer + SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE,
AES_cbc_encrypt(&encrypted_buffer[SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE],
&buffer[SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE],
file_size - SHA256_DIGEST_LENGTH - wvcdm::KEY_IV_SIZE,
&aes_key, iv_buffer, AES_DECRYPT);
@@ -263,12 +258,12 @@ bool UsageTable::SaveToFile() {
// Now save data to the file as seen in the constructor, above.
size_t file_size = sizeof(StoredUsageTable) +
table_.size() * sizeof(AlignedStoredUsageEntry);
uint8_t buffer[file_size];
uint8_t encrypted_buffer[file_size];
StoredUsageTable *stored_table = reinterpret_cast<StoredUsageTable *>(buffer);
std::vector<uint8_t> buffer(file_size);
std::vector<uint8_t> encrypted_buffer(file_size);
StoredUsageTable *stored_table =
reinterpret_cast<StoredUsageTable *>(&buffer[0]);
StoredUsageTable *encrypted_table =
reinterpret_cast<StoredUsageTable *>(encrypted_buffer);
memset(buffer, 0, file_size);
reinterpret_cast<StoredUsageTable *>(&encrypted_buffer[0]);
stored_table->generation = generation_;
stored_table->count = 0;
for (EntryMap::iterator i = table_.begin(); i != table_.end(); ++i) {
@@ -287,15 +282,15 @@ bool UsageTable::SaveToFile() {
memcpy(iv_buffer, encrypted_table->iv, wvcdm::KEY_IV_SIZE);
AES_KEY aes_key;
AES_set_encrypt_key(&key[0], 128, &aes_key);
AES_cbc_encrypt(buffer + SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE,
encrypted_buffer + SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE,
AES_cbc_encrypt(&buffer[SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE],
&encrypted_buffer[SHA256_DIGEST_LENGTH + wvcdm::KEY_IV_SIZE],
file_size - SHA256_DIGEST_LENGTH - wvcdm::KEY_IV_SIZE,
&aes_key, iv_buffer, AES_ENCRYPT);
// Sign the table.
unsigned int sig_length = sizeof(stored_table->signature);
if (!HMAC(EVP_sha256(), &key[0], key.size(),
encrypted_buffer + SHA256_DIGEST_LENGTH,
&encrypted_buffer[SHA256_DIGEST_LENGTH],
file_size - SHA256_DIGEST_LENGTH, encrypted_table->signature,
&sig_length)) {
LOGE("UsageTable: Could not sign table.");
@@ -330,7 +325,7 @@ bool UsageTable::SaveToFile() {
LOGE("UsageTable: Could not save usage table: %s", path.c_str());
return false;
}
file.Write(reinterpret_cast<char *>(encrypted_buffer), file_size);
file.Write(reinterpret_cast<char *>(&encrypted_buffer[0]), file_size);
file.Close();
// On a real implementation, you should NOT put the generation number in
@@ -425,4 +420,5 @@ bool UsageTable::ComputeHash(const std::vector<uint8_t> &pst,
if (!SHA256_Final(&pst_hash[0], &context)) return false;
return true;
}
}; // namespace wvoec_mock
} // namespace wvoec_mock

View File

@@ -2,8 +2,8 @@
//
// Mock implementation of OEMCrypto APIs
//
#ifndef WVOEC_MOCK_OEMCRYPTO_USAGE_TABLE_MOCK_H_
#define WVOEC_MOCK_OEMCRYPTO_USAGE_TABLE_MOCK_H_
#ifndef OEMCRYPTO_USAGE_TABLE_MOCK_H_
#define OEMCRYPTO_USAGE_TABLE_MOCK_H_
#include <stdint.h>
#include <map>
@@ -101,6 +101,6 @@ class UsageTable {
CryptoEngine *ce_;
};
}; // namespace wvoec_mock
} // namespace wvoec_mock
#endif // WVOEC_MOCK_OEMCRYPTO_USAGE_TABLE_MOCK_H_
#endif // OEMCRYPTO_USAGE_TABLE_MOCK_H_

View File

@@ -1,7 +1,9 @@
// Copyright 2013 Google Inc. All Rights Reserved.
#ifndef WVOEC_MOCK_WV_KEYBOX_H_
#define WVOEC_MOCK_WV_KEYBOX_H_
#ifndef WV_KEYBOX_H_
#define WV_KEYBOX_H_
#include <stdint.h>
namespace wvoec_mock {
@@ -19,6 +21,6 @@ typedef struct { // 128 bytes total.
uint8_t crc_[4];
} WidevineKeybox;
}
} // namespace wvoec_mock
#endif // WVOEC_MOCK_WV_KEYBOX_H_
#endif // WV_KEYBOX_H_

View File

@@ -2,8 +2,8 @@
//
// Compute CRC32 Checksum. Needed for verification of WV Keybox.
//
#ifndef WVOEC_MOCK_WVCRC32_H_
#define WVOEC_MOCK_WVCRC32_H_
#ifndef WVCRC32_H_
#define WVCRC32_H_
#include <stdint.h>
@@ -12,4 +12,4 @@ uint32_t wvcrc32(const uint8_t* p_begin, int i_count);
// Convert to network byte order
uint32_t wvcrc32n(const uint8_t* p_begin, int i_count);
#endif // WVOEC_MOCK_WVCRC32_H_
#endif // WVCRC32_H_