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

@@ -562,7 +562,7 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
* as a successful comparison).
*
* 2. The enc_mac_keys pointer must be either null, or point inside the
* message. If the pointer enc_mac_keys is not null, [e]the API shall verify
* message. If the pointer enc_mac_keys is not null, the API shall verify
* that the two pointers enc_mac_keys_iv and enc_mac_keys point to locations in
* the message. I.e. (message <= p && p < message+message_length)for p in
* each of enc_mac_keys_iv, enc_mac_keys. If not, return
@@ -603,8 +603,8 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
* license from being loaded more than once, and will be used for online
* streaming.
*
* - If Replay_Control is 2 = Require existing Session Usage table entry or
* Nonce”, then OEMCrypto will check the Session Usage table for an existing
* - If Replay_Control is 2 = "Require existing Session Usage table entry or
* Nonce", then OEMCrypto will check the Session Usage table for an existing
* entry with the same pst.
*
* --- If the pst is not in the table yet, a new entry will be created in the
@@ -867,8 +867,8 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
* secure buffer.
*
* If the session has an entry in the Usage Table, then OEMCrypto will update the
* time_of_last_decrypt. If the status of the entry is unused, then change the
* status to active and set the time_of_first_decrypt.[f]
* time_of_last_decrypt. If the status of the entry is "unused", then change the
* status to "active" and set the time_of_first_decrypt.
*
*
* Verification:
@@ -877,7 +877,7 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
*
* 1. If the current keys control block has a nonzero Duration field, then the
* API shall verify that the duration is greater than the sessions elapsed time
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED[g].
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
*
* 2. If the current keys control block has the Data_Path_Type bit set, then the
* API shall verify that the output buffer is secure or direct. If not, return
@@ -893,8 +893,8 @@ OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
* current version is not at least as high as that in the control block, then
* return OEMCrypto_ERROR_INSUFFICIENT_HDCP.
*
* 1. If the current session has an entry in the Usage Table, and the status of
* that entry is inactive, then return OEMCrypto_ERROR_INVALID_SESSION.[h]
* 5. If the current session has an entry in the Usage Table, and the status of
* that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION.
*
* If the flag is_encrypted is false, then no verification is performed. This
* call shall copy clear data even when there are no keys loaded, or there is no
@@ -1160,11 +1160,11 @@ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
* GenerateDerivedKeys.
*
* After decrypting enc_rsa_key, If the first four bytes of the buffer are the
* string SIGN, then the actual RSA key begins on the 9th byte of the buffer.
* The second four bytes of the buffer is the 32 bit field allowed_schemes,
* string "SIGN", then the actual RSA key begins on the 9th byte of the buffer.
* The second four bytes of the buffer is the 32 bit field "allowed_schemes",
* of type RSA_Padding_Scheme, which is used in OEMCrypto_GenerateRSASignature. The
* value of allowed_schemes must also be wrapped with RSA key. We recommend
* storing the magic string SIGN with the key to distinguish keys that have a
* storing the magic string "SIGN" with the key to distinguish keys that have a
* value for allowed_schemes from those that should use the default
* allowed_schemes. Devices that do not support the alternative signing
* algorithms may refuse to load these keys and return an error of
@@ -1173,7 +1173,7 @@ OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
* authentication when acting as a ChromeCast receiver. This is not needed for
* devices that wish to send data to a ChromeCast.
*
* If the first four bytes of the buffer enc_rsa_key are not the string SIGN,
* If the first four bytes of the buffer enc_rsa_key are not the string "SIGN",
* then the default value of allowed_schemes = 1 will be used.
*
* Verification:
@@ -1262,7 +1262,7 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
* the one verified and wrapped by OEMCrypto_RewrapDeviceRSAKey. The RSA private
* key should be stored in secure memory.
*
* If the bit field allowed_schemes was wrapped with this RSA key, its value
* If the bit field "allowed_schemes" was wrapped with this RSA key, its value
* will be loaded and stored with the RSA key. If there was not bit field
* wrapped with the RSA key, the key will use a default value of 1 = RSASSA-PSS
* with SHA1.
@@ -1550,8 +1550,8 @@ bool OEMCrypto_SupportsUsageTable();
* This function encrypts a generic buffer of data using the current key.
*
* If the session has an entry in the Usage Table, then OEMCrypto will update the
* time_of_last_decrypt. If the status of the entry is unused, then change the
* status to active and set the time_of_first_decrypt.
* time_of_last_decrypt. If the status of the entry is "unused", then change the
* status to "active" and set the time_of_first_decrypt.
*
* Verification:
* The following checks should be performed. If any check fails, an error is
@@ -1562,7 +1562,7 @@ bool OEMCrypto_SupportsUsageTable();
* API shall verify that the duration is greater than the sessions elapsed time
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
* 3. If the current session has an entry in the Usage Table, and the status of
* that entry is inactive, then return OEMCrypto_ERROR_INVALID_SESSION.
* that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION.
*
* Parameters:
* session (in) - crypto session identifier.
@@ -1602,8 +1602,8 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session,
* This function decrypts a generic buffer of data using the current key.
*
* If the session has an entry in the Usage Table, then OEMCrypto will update the
* time_of_last_decrypt. If the status of the entry is unused, then change the
* status to active and set the time_of_first_decrypt.
* time_of_last_decrypt. If the status of the entry is "unused", then change the
* status to "active" and set the time_of_first_decrypt.
*
* Verification:
* The following checks should be performed. If any check fails, an error is
@@ -1616,7 +1616,7 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session,
* API shall verify that the duration is greater than the sessions elapsed time
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
* 4. If the current session has an entry in the Usage Table, and the status of
* that entry is inactive, then return OEMCrypto_ERROR_INVALID_SESSION.
* that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION.
*
* Parameters:
* session (in) - crypto session identifier.
@@ -1657,8 +1657,8 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session,
* This function signs a generic buffer of data using the current key.
*
* If the session has an entry in the Usage Table, then OEMCrypto will update the
* time_of_last_decrypt. If the status of the entry is unused, then change the
* status to active and set the time_of_first_decrypt.
* time_of_last_decrypt. If the status of the entry is "unused", then change the
* status to "active" and set the time_of_first_decrypt.
*
* Verification:
* The following checks should be performed. If any check fails, an error is
@@ -1668,7 +1668,7 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session,
* API shall verify that the duration is greater than the sessions elapsed time
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
* 3. If the current session has an entry in the Usage Table, and the status of
* that entry is inactive, then return OEMCrypto_ERROR_INVALID_SESSION.
* that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION.
*
* Parameters:
* session (in) - crypto session identifier.
@@ -1714,8 +1714,8 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
* current key.
*
* If the session has an entry in the Usage Table, then OEMCrypto will update the
* time_of_last_decrypt. If the status of the entry is unused, then change the
* status to active and set the time_of_first_decrypt.
* time_of_last_decrypt. If the status of the entry is "unused", then change the
* status to "active" and set the time_of_first_decrypt.
*
* Verification:
* The following checks should be performed. If any check fails, an error is
@@ -1730,7 +1730,7 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
* API shall verify that the duration is greater than the sessions elapsed time
* clock. If not, return OEMCrypto_ERROR_KEY_EXPIRED.
* 5. If the current session has an entry in the Usage Table, and the status of
* that entry is inactive, then return OEMCrypto_ERROR_INVALID_SESSION.
* that entry is "inactive", then return OEMCrypto_ERROR_INVALID_SESSION.
*
* Parameters:
* session (in) - crypto session identifier.
@@ -1797,8 +1797,8 @@ OEMCryptoResult OEMCrypto_UpdateUsageTable();
*
* Description:
* Find the entry in the Usage Table with a matching PST. Mark the status of
* that entry as inactive. If it corresponds to an open session, the status of
* that session will also be marked as inactive. Then OEMCrypto will increment
* that entry as "inactive". If it corresponds to an open session, the status of
* that session will also be marked as "inactive". Then OEMCrypto will increment
* Usage Tables generation number, sign, encrypt, and save the Usage Table.
*
* If no entry in the Usage Table has a matching PST, return the error
@@ -1934,7 +1934,7 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
* the computed signature matches the signature passed in. The signature will be
* computed using HMAC-SHA256 and the mac_key_server. If they do not match,
* return OEMCrypto_ERROR_SIGNATURE_FAILURE.
* 3. If the session is not associated with an entry in the Usage Table, return
* 3. If the session is not associated with an entry in the Usage Table, return
* OEMCrypto_ERROR_UNKNOWN_FAILURE.
* 4. If the pst passed in as a parameter does not match that in the Usage Table,
* return OEMCrypto_ERROR_UNKNOWN_FAILURE.

View File

@@ -3,11 +3,14 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
src/oemcrypto_engine_device_properties.cpp \
src/oemcrypto_engine_mock.cpp \
src/oemcrypto_key_mock.cpp \
src/oemcrypto_keybox_mock.cpp \
src/oemcrypto_usage_table_mock.cpp \
src/oemcrypto_keybox_testkey.cpp \
src/oemcrypto_logging.cpp \
src/oemcrypto_mock.cpp \
src/oemcrypto_usage_table_mock.cpp \
src/wvcrc.cpp \
LOCAL_MODULE_TAGS := tests

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_

View File

@@ -24,115 +24,95 @@ class OEMCryptoLoggingTest : public ::testing::Test {
};
TEST_F(OEMCryptoLoggingTest, TestDumpHexFunctions) {
uint8_t vector[] = { 0xFA, 0x11 , 0x28 , 0x33 };
std::string buffer = "";
wvoec_mock::dump_hex_helper(buffer, "name", vector, (size_t)4);
ASSERT_EQ(buffer, "name = \n wvcdm::a2b_hex(\"FA112833\");\n");
uint8_t vector[] = {0xFA, 0x11, 0x28, 0x33};
std::string buffer;
wvoec_mock::dump_hex_helper(buffer, "name", vector, 4u);
ASSERT_EQ("name = \n wvcdm::a2b_hex(\"FA112833\");\n", buffer);
buffer = "";
uint8_t vector2[] = { 0xFA, 0x11 , 0x28 , 0x33 ,
0xFA, 0x11 , 0x28 , 0x33 , 0xFA, 0x11 ,
0x28 , 0x33 , 0xFA, 0x11 , 0x28 , 0x33 , 0xFA, 0x11 , 0x28 , 0x33 ,
0xFA, 0x11 , 0x28 , 0x33 , 0x01, 0x14 , 0x28 , 0xAB, 0xFA, 0xCD ,
0xEF , 0x67, 0x01, 0x14 , 0x28 , 0xAB, 0xFA, 0xCD , 0xEF , 0x67 };
wvoec_mock::dump_hex_helper(buffer, "name", vector2, (size_t)40);
uint8_t vector2[] = {
0xFA, 0x11, 0x28, 0x33, 0xFA, 0x11, 0x28, 0x33, 0xFA, 0x11,
0x28, 0x33, 0xFA, 0x11, 0x28, 0x33, 0xFA, 0x11, 0x28, 0x33,
0xFA, 0x11, 0x28, 0x33, 0x01, 0x14, 0x28, 0xAB, 0xFA, 0xCD,
0xEF, 0x67, 0x01, 0x14, 0x28, 0xAB, 0xFA, 0xCD, 0xEF, 0x67,
};
ASSERT_EQ(buffer, "name = \n wvcdm::a2b_hex(\"FA112833FA112833FA112833F"
"A112833FA112833FA112833011428ABFACDEF67\"\n \""
"011428ABFACDEF67\");\n");
buffer.clear(); // dump_hex_helper appends to buffer
wvoec_mock::dump_hex_helper(buffer, "name", vector2, 40u);
ASSERT_EQ(
"name = \n "
"wvcdm::a2b_hex("
"\"FA112833FA112833FA112833FA112833FA112833FA112833011428ABFACDEF67\"\n "
" \"011428ABFACDEF67\");\n",
buffer);
buffer = "";
wvoec_mock::dump_array_part_helper(buffer, "array",
(size_t) 5, "name", vector2, (size_t) 40);
char* exp = "std::string s5_name = \n wvcdm::a2b_hex(\"FA112833FA112833F"
"A112833FA112833FA112833FA112833011428ABFACDEF67\"\n "
" \"011428ABFACDEF67\");\narray[5].name = message_ptr + me"
"ssage.find(s5_name.data());\n";
ASSERT_EQ(buffer, exp);
buffer.clear(); // dump_hex_helper appends to buffer
wvoec_mock::dump_array_part_helper(buffer, "array", 5u, "name", vector2, 40u);
ASSERT_EQ(
"std::string s5_name = \n "
"wvcdm::a2b_hex("
"\"FA112833FA112833FA112833FA112833FA112833FA112833011428ABFACDEF67\"\n "
" \"011428ABFACDEF67\");\narray[5].name = message_ptr + "
"message.find(s5_name.data());\n",
buffer);
buffer = "";
wvoec_mock::dump_array_part_helper(buffer, "array", (size_t) 5,
"name", NULL, (size_t) 40);
ASSERT_EQ(buffer, "array[5].name = NULL;\n");
buffer.clear(); // dump_hex_helper appends to buffer
wvoec_mock::dump_array_part_helper(buffer, "array", 5u, "name", NULL, 40u);
ASSERT_EQ("array[5].name = NULL;\n", buffer);
}
TEST_F(OEMCryptoLoggingTest, TestChangeLoggingLevel) {
wvcdm::LogPriority default_logging_level = wvcdm::LOG_WARN;
wvoec_mock::SetLoggingLevel(1);
ASSERT_EQ(wvcdm::g_cutoff, default_logging_level);
wvoec_mock::SetLoggingLevel(wvcdm::LOG_WARN);
ASSERT_EQ(wvcdm::LOG_WARN, wvcdm::g_cutoff);
wvoec_mock::SetLoggingLevel(2);
ASSERT_EQ(wvcdm::g_cutoff, wvcdm::LOG_INFO);
wvoec_mock::SetLoggingLevel(wvcdm::LOG_INFO);
ASSERT_EQ(wvcdm::LOG_INFO, wvcdm::g_cutoff);
wvoec_mock::SetLoggingSettings(
wvcdm::LOG_WARN,
wvoec_mock::kLoggingDumpTraceAll);
ASSERT_EQ(wvcdm::g_cutoff, wvcdm::LOG_WARN);
ASSERT_EQ(wvoec_mock::LogCategoryEnabled(
wvoec_mock::kLoggingDumpTraceAll), true);
wvoec_mock::SetLoggingSettings(wvcdm::LOG_WARN,
wvoec_mock::kLoggingDumpTraceAll);
ASSERT_EQ(wvcdm::LOG_WARN, wvcdm::g_cutoff);
ASSERT_TRUE(wvoec_mock::LogCategoryEnabled(wvoec_mock::kLoggingDumpTraceAll));
wvoec_mock::TurnOffLoggingForAllCategories();
wvoec_mock::SetLoggingLevel(wvcdm::LOG_VERBOSE);
ASSERT_EQ(wvcdm::g_cutoff, wvcdm::LOG_VERBOSE);
ASSERT_EQ(wvcdm::LOG_VERBOSE, wvcdm::g_cutoff);
wvoec_mock::SetLoggingLevel(1);
wvoec_mock::SetLoggingLevel(wvcdm::LOG_WARN);
}
namespace wvoec_mock {
TEST_F(OEMCryptoLoggingTest, TestChangeLoggingCategories) {
using namespace wvoec_mock;
TurnOffLoggingForAllCategories();
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceDecryption |
kLoggingTraceOEMCryptoCalls), false);
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceDecryption |
kLoggingTraceOEMCryptoCalls));
AddLoggingForCategories(kLoggingDumpKeyControlBlocks |
kLoggingDumpDerivedKeys);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpKeyControlBlocks), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceUsageTable), false);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpTraceAll), true);
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceUsageTable));
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpTraceAll));
RemoveLoggingForCategories(kLoggingDumpKeyControlBlocks |
kLoggingTraceUsageTable);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpKeyControlBlocks), false);
kLoggingTraceUsageTable);
ASSERT_FALSE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpDerivedKeys), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceUsageTable), false);
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpDerivedKeys));
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceUsageTable));
TurnOffLoggingForAllCategories();
bool flag = false;
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
flag = true;
}
ASSERT_EQ(flag, false);
ASSERT_FALSE(LogCategoryEnabled(kLoggingTraceUsageTable));
AddLoggingForCategories(kLoggingDumpTraceAll);
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
flag = true;
}
ASSERT_EQ(flag, true);
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceOEMCryptoCalls), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpContentKeys), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpKeyControlBlocks), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpDerivedKeys), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceNonce), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceDecryption), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceUsageTable), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpTraceAll), true);
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceOEMCryptoCalls));
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpContentKeys));
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpDerivedKeys));
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceNonce));
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceDecryption));
ASSERT_TRUE(LogCategoryEnabled(kLoggingTraceUsageTable));
ASSERT_TRUE(LogCategoryEnabled(kLoggingDumpTraceAll));
flag= false;
RemoveLoggingForCategories(kLoggingDumpKeyControlBlocks);
if ( LogCategoryEnabled(kLoggingDumpKeyControlBlocks) ) {
flag = true;
}
ASSERT_EQ(flag, false);
ASSERT_FALSE(LogCategoryEnabled(kLoggingDumpKeyControlBlocks));
}
} // namespace wvoec_mock
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
wvcdm::InitLogging(argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -24,6 +24,7 @@
#include <string>
#include <vector>
#include "log.h"
#include "OEMCryptoCENC.h"
#include "oemcrypto_key_mock.h"
#include "properties.h"
@@ -1547,13 +1548,14 @@ class OEMCryptoClientTest : public ::testing::Test {
protected:
OEMCryptoClientTest() {}
void SetUp() {
virtual void SetUp() {
::testing::Test::SetUp();
wvcdm::Properties::Init();
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
wvcdm::g_cutoff = wvcdm::LOG_INFO;
}
void TearDown() {
virtual void TearDown() {
OEMCrypto_Terminate();
::testing::Test::TearDown();
}
@@ -1868,18 +1870,43 @@ TEST_F(OEMCryptoClientTest, GenerateDerivedKeys) {
class DISABLED_TestKeybox : public OEMCryptoClientTest {
protected:
void SetUp() {
virtual void SetUp() {
OEMCryptoClientTest::SetUp();
InstallKeybox(kDefaultKeybox, true);
OEMCrypto_DeleteUsageTable();
}
virtual void TearDown() {
InstallKeybox(kDefaultKeybox, true);
OEMCryptoClientTest::TearDown();
}
bool IsDefaultKeyboxInstalled() {
uint8_t key_data[256];
size_t key_data_len = sizeof(key_data);
OEMCryptoResult sts = OEMCrypto_GetKeyData(key_data, &key_data_len);
uint32_t* data = reinterpret_cast<uint32_t*>(key_data);
uint32_t system_id = htonl(data[1]);
return sts == OEMCrypto_SUCCESS && system_id == 0x1019;
}
void InstallKeybox(const wvoec_mock::WidevineKeybox& keybox, bool good) {
OEMCryptoResult sts;
uint8_t wrapped[sizeof(wvoec_mock::WidevineKeybox)];
size_t length = sizeof(wvoec_mock::WidevineKeybox);
sts = OEMCrypto_WrapKeybox(reinterpret_cast<const uint8_t*>(&keybox),
sizeof(keybox), wrapped, &length, NULL, 0);
if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED &&
&keybox == &kDefaultKeybox &&
IsDefaultKeyboxInstalled()) {
// Allow implementations which don't support installation to continue
// so long as:
// 1) we wanted to install the default keybox AND
// 2) the default keybox is already installed.
return;
}
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts = OEMCrypto_InstallKeybox(wrapped, sizeof(keybox));
if (good) {
@@ -1937,7 +1964,6 @@ TEST_F(DISABLED_TestKeybox, BadCRCKeybox) {
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_CRC, sts);
InstallKeybox(kDefaultKeybox, true);
}
TEST_F(DISABLED_TestKeybox, BadMagicKeybox) {
@@ -1947,7 +1973,6 @@ TEST_F(DISABLED_TestKeybox, BadMagicKeybox) {
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_MAGIC, sts);
InstallKeybox(kDefaultKeybox, true);
}
TEST_F(DISABLED_TestKeybox, BadDataKeybox) {
@@ -1957,11 +1982,9 @@ TEST_F(DISABLED_TestKeybox, BadDataKeybox) {
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_CRC, sts);
InstallKeybox(kDefaultKeybox, true);
}
TEST_F(DISABLED_TestKeybox, GenerateSignature) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -1995,7 +2018,6 @@ TEST_F(DISABLED_TestKeybox, GenerateSignature) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyNoNonce) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2005,7 +2027,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyNoNonce) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithNonce) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2015,7 +2036,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithNonce) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithNoMAC) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2053,7 +2073,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithNoMAC) {
of all the pointers. It should reject a message if the pointer does
not point into the message buffer */
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange1) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2072,7 +2091,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange1) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange2) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2091,7 +2109,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange2) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange3) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2110,7 +2127,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange3) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange4) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2130,7 +2146,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange4) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange5) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2148,7 +2163,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange5) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange6) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2169,7 +2183,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange6) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange7) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2190,7 +2203,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange7) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadNonce) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2205,7 +2217,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadNonce) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithRepeatNonce) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2229,7 +2240,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithRepeatNonce) {
}
TEST_F(DISABLED_TestKeybox, LoadKeyWithBadVerification) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2246,7 +2256,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadVerification) {
}
TEST_F(DISABLED_TestKeybox, LoadKeysBadSignature) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2261,7 +2270,6 @@ TEST_F(DISABLED_TestKeybox, LoadKeysBadSignature) {
}
TEST_F(DISABLED_TestKeybox, LoadKeysWithNoDerivedKeys) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
// s.GenerateDerivedKeys();
@@ -2279,7 +2287,6 @@ class DISABLED_DecryptWithHDCP : public DISABLED_TestKeybox,
public:
void DecryptWithHDCP(OEMCrypto_HDCP_Capability version) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
OEMCrypto_HDCP_Capability current, maximum;
sts = OEMCrypto_GetHDCPCapability(&current, &maximum);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
@@ -2339,7 +2346,7 @@ TEST_P(DISABLED_RefreshKeyTest, RefreshWithNonce) {
s.RefreshTestKeys(num_keys_, wvoec_mock::kControlNonceEnabled, nonce, true);
}
TEST_P(DISABLED_RefreshKeyTest, RefresNoNonce) {
TEST_P(DISABLED_RefreshKeyTest, RefreshNoNonce) {
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2392,7 +2399,6 @@ INSTANTIATE_TEST_CASE_P(TestRefreshEachKeys, DISABLED_RefreshKeyTest,
//
TEST_F(DISABLED_TestKeybox, Decrypt) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2405,7 +2411,6 @@ TEST_F(DISABLED_TestKeybox, Decrypt) {
TEST_F(DISABLED_TestKeybox, DecryptZeroDuration) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2418,7 +2423,6 @@ TEST_F(DISABLED_TestKeybox, DecryptZeroDuration) {
TEST_F(DISABLED_TestKeybox, DecryptWithOffset) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2513,7 +2517,6 @@ vector<uint8_t> EncryptCTR(const vector<uint8_t>& key,
TEST_F(DISABLED_TestKeybox, DecryptWithNearWrap) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2564,7 +2567,6 @@ TEST_F(DISABLED_TestKeybox, DecryptWithNearWrap) {
TEST_F(DISABLED_TestKeybox, DecryptUnencrypted) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2611,7 +2613,6 @@ TEST_F(DISABLED_TestKeybox, DecryptUnencrypted) {
TEST_F(DISABLED_TestKeybox, DecryptUnencryptedNoKey) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
@@ -2650,7 +2651,6 @@ TEST_F(DISABLED_TestKeybox, DecryptUnencryptedNoKey) {
TEST_F(DISABLED_TestKeybox, DecryptSecureToClear) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2664,7 +2664,6 @@ TEST_F(DISABLED_TestKeybox, DecryptSecureToClear) {
TEST_F(DISABLED_TestKeybox, KeyDuration) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2710,7 +2709,6 @@ TEST_F(DISABLED_TestKeybox, ValidateRSATestKeys) {
}
TEST_F(DISABLED_TestKeybox, CertificateProvision) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2727,7 +2725,6 @@ TEST_F(DISABLED_TestKeybox, CertificateProvision) {
}
TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange1) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2755,7 +2752,6 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange1) {
}
TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange2) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2785,7 +2781,6 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange2) {
}
TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange3) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2816,7 +2811,6 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRange3) {
}
TEST_F(DISABLED_TestKeybox, CertificateProvisionBadSignature) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2845,7 +2839,6 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadSignature) {
}
TEST_F(DISABLED_TestKeybox, CertificateProvisionBadNonce) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2874,7 +2867,6 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadNonce) {
}
TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRSAKey) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -2904,7 +2896,6 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRSAKey) {
TEST_F(DISABLED_TestKeybox, LoadWrappedRSAKey) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
std::vector<uint8_t> wrapped_rsa_key;
CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true);
@@ -2917,7 +2908,6 @@ TEST_F(DISABLED_TestKeybox, LoadWrappedRSAKey) {
TEST_F(DISABLED_TestKeybox, RSASignature) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
std::vector<uint8_t> wrapped_rsa_key;
CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true);
@@ -2955,7 +2945,6 @@ TEST_F(DISABLED_TestKeybox, RSASignature) {
}
TEST_F(DISABLED_TestKeybox, LoadRSASessionKey) {
InstallKeybox(kDefaultKeybox, true);
std::vector<uint8_t> wrapped_rsa_key;
CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true);
Session s;
@@ -2965,7 +2954,6 @@ TEST_F(DISABLED_TestKeybox, LoadRSASessionKey) {
TEST_F(DISABLED_TestKeybox, CertificateDecrypt) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
std::vector<uint8_t> wrapped_rsa_key;
CreateWrappedRSAKey(&wrapped_rsa_key, kSign_RSASSA_PSS, true);
Session s;
@@ -3059,7 +3047,6 @@ class DISABLED_AlternateRSAAlgorithms : public DISABLED_TestKeybox {
}
void LoadWithAllowedSchemes(uint32_t schemes, bool force) {
InstallKeybox(kDefaultKeybox, true);
CreateWrappedRSAKey(&wrapped_rsa_key_, schemes, force);
key_loaded_ = (wrapped_rsa_key_.size() > 0);
}
@@ -3355,7 +3342,6 @@ class DISABLED_AlternateRSAKey : public DISABLED_TestKeybox {
void LoadWithAllowedSchemes(uint32_t schemes, bool force) {
BuildRSAKey();
InstallKeybox(kDefaultKeybox, true);
CreateWrappedRSAKey(&wrapped_rsa_key_, schemes, force, &encoded_key_[0],
encoded_key_.size());
key_loaded_ = (wrapped_rsa_key_.size() > 0);
@@ -4132,7 +4118,6 @@ class DISABLED_GenericDRMTest : public DISABLED_TestKeybox {
void BadEncrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm,
size_t buffer_length) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4154,7 +4139,6 @@ class DISABLED_GenericDRMTest : public DISABLED_TestKeybox {
void BadDecrypt(unsigned int key_index, OEMCrypto_Algorithm algorithm,
size_t buffer_length) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4175,7 +4159,6 @@ class DISABLED_GenericDRMTest : public DISABLED_TestKeybox {
void BadSign(unsigned int key_index, OEMCrypto_Algorithm algorithm) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4199,7 +4182,6 @@ class DISABLED_GenericDRMTest : public DISABLED_TestKeybox {
void BadVerify(unsigned int key_index, OEMCrypto_Algorithm algorithm,
size_t signature_size, bool alter_data) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4222,7 +4204,6 @@ class DISABLED_GenericDRMTest : public DISABLED_TestKeybox {
};
TEST_F(DISABLED_GenericDRMTest, GenericKeyLoad) {
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4233,7 +4214,6 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyLoad) {
TEST_F(DISABLED_GenericDRMTest, GenericKeyEncrypt) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4264,7 +4244,6 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyBadEncrypt) {
TEST_F(DISABLED_GenericDRMTest, GenericKeyDecrypt) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4286,7 +4265,6 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyDecrypt) {
TEST_F(DISABLED_GenericDRMTest, GenericSecureToClear) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4318,7 +4296,6 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyBadDecrypt) {
TEST_F(DISABLED_GenericDRMTest, GenericKeySign) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4355,7 +4332,6 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyBadSign) {
TEST_F(DISABLED_GenericDRMTest, GenericKeyVerify) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4387,7 +4363,6 @@ TEST_F(DISABLED_GenericDRMTest, GenericKeyBadVerify) {
TEST_F(DISABLED_GenericDRMTest, KeyDurationEncrypt) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4424,7 +4399,6 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationEncrypt) {
TEST_F(DISABLED_GenericDRMTest, KeyDurationDecrypt) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4459,7 +4433,6 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationDecrypt) {
TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();
@@ -4498,7 +4471,6 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) {
TEST_F(DISABLED_GenericDRMTest, KeyDurationVerify) {
OEMCryptoResult sts;
InstallKeybox(kDefaultKeybox, true);
Session s;
s.open();
s.GenerateDerivedKeys();