Merge Changes from CDM repository

This CL merges the following changes from the Widevine repository:

Avoid CdmSession reinitialization
https://widevine-internal-review.googlesource.com/#/c/10530/

Fix timer-related unit tests.
https://widevine-internal-review.googlesource.com/#/c/10510/

Correct return statement
bug: 15590802
https://widevine-internal-review.googlesource.com/#/c/10553/

Usage reporting fixes
bug/15388863
https://widevine-internal-review.googlesource.com/#/c/10460/

Make public methods virtual
https://widevine-internal-review.googlesource.com/#/c/10500/

Fix the SetTimer contract in the CDM.
https://widevine-internal-review.googlesource.com/#/c/10493/

Move inline CDM methods, add OVERRIDE.
https://widevine-internal-review.googlesource.com/#/c/10475/

Simplify storage APIs related cleanup.
https://widevine-internal-review.googlesource.com/#/c/10473/

Duration values are not correctly reported when queried
b/15592374
https://widevine-internal-review.googlesource.com/#/c/10437/

Propagate IsKeyValid() through ContentDecryptionModule.
https://widevine-internal-review.googlesource.com/#/c/10483/

Minor clean up in config_test_env.
https://widevine-internal-review.googlesource.com/#/c/10440/

General clean up.
https://widevine-internal-review.googlesource.com/#/c/10441/

Refactor HttpSocket and simplify UrlRequest interface.
https://widevine-internal-review.googlesource.com/#/c/10410/

Install good keybox at end of unit tests
b/15385981
https://widevine-internal-review.googlesource.com/#/c/10374/

Privacy crypto fixes
b/15475012
https://widevine-internal-review.googlesource.com/#/c/10383/

Incorporate header files to resolve build issued based on customers feedback.
https://widevine-internal-review.googlesource.com/#/c/10420/

Support unprovisioning
b/12247651
https://widevine-internal-review.googlesource.com/#/c/10356/

Correct usage of Host::Allocate and Cdm::Decrypt.
https://widevine-internal-review.googlesource.com/#/c/10378/

Fix logging bug, arguments in wrong order.
https://widevine-internal-review.googlesource.com/#/c/10380/

Rename types that look like constants.
https://widevine-internal-review.googlesource.com/#/c/10379/

Fix offline test failures
b/13909635
https://widevine-internal-review.googlesource.com/#/c/10348/

Add -DUNIT_TEST to the unit test makefile for Android
https://widevine-internal-review.googlesource.com/#/c/10375/

Refactor privacy-crypto and add dummy version.
https://widevine-internal-review.googlesource.com/#/c/10353/

Remove References to Apiary
https://widevine-internal-review.googlesource.com/#/c/9924/

Delete oldest entry in usage table when full
bug: 15184824
https://widevine-internal-review.googlesource.com/#/c/10295/

Port DeviceFiles to iOS.
https://widevine-internal-review.googlesource.com/#/c/10355/

Make testing functions in DeviceFiles private.
https://widevine-internal-review.googlesource.com/#/c/10354/

Add RSA encryption to haystack
https://widevine-internal-review.googlesource.com/#/c/10280/

Add string and vector includes to CDM header.
https://widevine-internal-review.googlesource.com/#/c/10352/

First version of oemcrypto logging
https://widevine-internal-review.googlesource.com/#/c/10252/

Update Names of Secure Stop Methods
bug: 11987015
https://widevine-internal-review.googlesource.com/#/c/10152/

Adjust timing on the Usage Table unit test
https://widevine-internal-review.googlesource.com/#/c/10307/

Fix all compiler warnings in CDM source release.
https://widevine-internal-review.googlesource.com/#/c/10293/

Fix memset bug: args in wrong order
https://widevine-internal-review.googlesource.com/#/c/10292/

Partial revert of 'Remove refs to test prov server, Level3 support...'
https://widevine-internal-review.googlesource.com/#/c/10281/

Pack structure OEMCrypto_PST_Report
https://widevine-internal-review.googlesource.com/#/c/10243/

Remove refs to test prov server, Level3 support; remove dead code
https://widevine-internal-review.googlesource.com/#/c/10220/

Partial revert of 'Document data strings; clean up license server parameters.'
https://widevine-internal-review.googlesource.com/#/c/10188/

Document data strings; clean up license server parameters.
https://widevine-internal-review.googlesource.com/#/c/10120/

Fix broken build after partner branch merge.
https://widevine-internal-review.googlesource.com/#/c/10181/

TODO Cleanup - core/src, core/include
https://widevine-internal-review.googlesource.com/#/c/9965/

TODO Cleanup - cdm, chromium, core/test.
https://widevine-internal-review.googlesource.com/#/c/9419/

Remove unneeded properties.
https://widevine-internal-review.googlesource.com/#/c/10162/

Change-Id: If2bb9d743a562a3875bebb91933c0aaadea286b2
This commit is contained in:
Fred Gylys-Colwell
2014-06-25 13:02:54 -07:00
parent 8a8feb747c
commit b5e8b87fed
66 changed files with 2927 additions and 1998 deletions

View File

@@ -9,9 +9,9 @@
#ifndef OEMCRYPTO_CENC_H_
#define OEMCRYPTO_CENC_H_
#include<stdbool.h>
#include<stddef.h>
#include<stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {

View File

@@ -0,0 +1,65 @@
// Copyright 2014 Google Inc. All Rights Reserved.
#ifndef WVOEC_OEMCRYPTO_LOGGING_H_
#define WVOEC_OEMCRYPTO_LOGGING_H_
#include "OEMCryptoCENC.h"
#include "log.h"
#include <string>
#include <iostream>
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;
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 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

View File

@@ -1,110 +0,0 @@
#
# Builds liboemcrypto_mock.so
#
#PROJECTS_ROOT = ~projects
#
ifndef PROJECTS_ROOT
PROJECTS_ROOT = ../../../..
endif
CDM_ROOT = $(PROJECTS_ROOT)/cdm
CDM_SRC_PATH = $(CDM_ROOT)/cdm
CDM_INCLUDE_PATH = $(CDM_SRC_PATH)/include
EUREKA_ROOT = $(PROJECTS_ROOT)/eureka/eureka/src
CHROME_ROOT = $(EUREKA_ROOT)/chromium/src
#
# build outputs should go into Chrome repository, such as ../chromium/src/out
# or some local equivalent.
# WARNING: splitting outputs from CHROME_ROOT can lead to build errors
ifndef CHROME_ROOT
CHROME_ROOT = $(CDM_ROOT)/out
endif
# TARGET_PLATFORM from {x86,eureka}
ifndef TARGET_PLATFORM
TARGET_PLATFORM = x86
endif
# TARGET_BUILD from {debug,release}
ifndef TARGET_BUILD
TARGET_BUILD = debug
endif
ifeq ($(TARGET_PLATFORM),x86)
BUILDPLATFORM = out_x86_linux
else ifeq ($(TARGET_PLATFORM),eureka)
BUILDPLATFORM = out_arm_eureka
else
BUILDPLATFORM = UNKNOWN
endif
ifeq ($(TARGET_BUILD),debug)
BUILDTYPE = Debug
else ifeq ($(TARGET_BUILD),release)
BUILDTYPE = Release
else
BUILDTYPE = UNKNOWN
endif
BUILDPATH = $(CHROME_ROOT)/$(BUILDPLATFORM)/$(BUILDTYPE)
OBJPATH = $(BUILDPATH)/obj
#primary build target
TARGET_LIB = liboemcrypto_mock.so
LIB_OBJECTS = \
oemcrypto_mock.o \
oemcrypto_engine_mock.o \
oemcrypto_key_mock.o \
oemcrypto_keybox_mock.o \
oemcrypto_usage_table_mock.o
INCLUDES = \
-I$(CDM_INCLUDE_PATH)
OBJECTDIR = $(OBJPATH)/mock
INSTALLDIR = $(BUILDPATH)
OBJECTS := $(patsubst %.o,$(OBJECTDIR)/%.o,$(LIB_OBJECTS))
CXXFLAGS = -m64 -fPIC -W -Wall -g -DCDM_TEST
LINK = $(CXX)
MKDIR = mkdir -p
$(INSTALLDIR)/$(TARGET_LIB): $(OBJECTDIR) $(INSTALLDIR) $(OBJECTS)
$(LINK) -v -fPIC -m64 -shared -static-libgcc $(SHLIBFLAGS) \
$(OBJECTS) \
--retain-symbols-file=OECsymbols.txt \
-Wl,-Bstatic \
-Wl,-Bdynamic -lcrypto \
-o $@
$(OBJECTDIR)/%.o: src/%.cpp
$(CXX) -c -DCDM_TEST $(CXXFLAGS) $(INCLUDES) $< -o $@
$(OBJECTDIR)/%.o: src/%.cc
$(CXX) -c -DCDM_TEST $(CXXFLAGS) $(INCLUDES) $< -o $@
test:
make -C test
clean:
$(RM) -rf $(OBJECTDIR)
$(RM) -rf $(INSTALLDIR)/$(TARGET_LIB)
$(OBJECTDIR):
@$(MKDIR) $@
$(INSTALLDIR):
@$(MKDIR) $@
.PHONY: $(OBJECTDIR)
.PHONY: $(INSTALLDIR)
.PHONY: clean
.PHONY: test

View File

@@ -11,6 +11,7 @@
#include "log.h"
#include "oemcrypto_key_mock.h"
#include "oemcrypto_logging.h"
#include "oemcrypto_usage_table_mock.h"
#include "openssl/aes.h"
#include "openssl/bio.h"
@@ -34,7 +35,7 @@ void ctr128_inc64(uint8_t* counter) {
uint32_t n = 16;
do {
if (++counter[--n] != 0) return;
} while (n>8);
} while (n > 8);
}
void dump_openssl_error() {
while (unsigned long err = ERR_get_error()) {
@@ -43,7 +44,7 @@ void dump_openssl_error() {
err, ERR_error_string(err, buffer));
}
}
}
} // namespace
namespace wvoec_mock {
@@ -76,7 +77,7 @@ void SessionKeyTable::Remove(const KeyId key_id) {
}
void SessionKeyTable::UpdateDuration(const KeyControlBlock& control) {
for(KeyMap::iterator it = keys_.begin(); it != keys_.end(); ++it) {
for (KeyMap::iterator it = keys_.begin(); it != keys_.end(); ++it) {
it->second->UpdateDuration(control);
}
}
@@ -157,17 +158,13 @@ bool SessionContext::DeriveKeys(const std::vector<uint8_t>& master_key,
return false;
}
#if 0 // Print Derived Keys to stdout.
std::cout << " mac_key_context = " << wvcdm::b2a_hex(mac_key_context)
<< std::endl;
std::cout << " enc_key_context = " << wvcdm::b2a_hex(enc_key_context)
<< std::endl;
std::cout << " mac_key_server = " << wvcdm::b2a_hex(mac_key_server)
<< std::endl;
std::cout << " mac_key_client = " << wvcdm::b2a_hex(mac_key_client)
<< std::endl;
std::cout << " enc_key = " << wvcdm::b2a_hex(enc_key) << std::endl;
#endif
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
LOGI((" mac_key_context = " + wvcdm::b2a_hex(mac_key_context)).c_str());
LOGI((" enc_key_context = " + wvcdm::b2a_hex(enc_key_context)).c_str());
LOGI((" mac_key_server = " + wvcdm::b2a_hex(mac_key_server)).c_str());
LOGI((" mac_key_client = " + wvcdm::b2a_hex(mac_key_client)).c_str());
LOGI((" enc_key = " + wvcdm::b2a_hex(enc_key)).c_str());
}
set_mac_key_server(mac_key_server);
set_mac_key_client(mac_key_client);
@@ -183,7 +180,7 @@ bool SessionContext::RSADeriveKeys(const std::vector<uint8_t>& enc_session_key,
return false;
}
if (enc_session_key.size() != static_cast<size_t>(RSA_size(rsa_key_))) {
LOGE("[RSADeriveKeys(): encrypted session key is wrong size:%zu, should be %d]",
LOGE("[RSADeriveKeys(): encrypted session key wrong size:%zu, expected %d]",
enc_session_key.size(), RSA_size(rsa_key_));
dump_openssl_error();
return false;
@@ -214,7 +211,6 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length) {
if (message == NULL || message_length == 0 ||
signature == NULL || signature_length == 0) {
LOGE("[OEMCrypto_GenerateSignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
@@ -305,8 +301,8 @@ bool SessionContext::GenerateRSASignature(const uint8_t* message,
return false;
}
// Pad the message with PKCS1 padding, and then encrypt.
int status = RSA_private_encrypt(message_length, message, signature,
rsa_key_, RSA_PKCS1_PADDING);
size_t status = RSA_private_encrypt(message_length, message, signature,
rsa_key_, RSA_PKCS1_PADDING);
if (status != *signature_length) {
LOGE("[GeneratRSASignature(): error in RSA private encrypt. status=%d]", status);
dump_openssl_error();
@@ -323,7 +319,6 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message,
size_t message_length,
const uint8_t* given_signature,
size_t signature_length) {
if (signature_length != SHA256_DIGEST_LENGTH) {
return false;
}
@@ -471,14 +466,14 @@ bool SessionContext::InstallKey(const KeyId& key_id,
return false;
}
#if 0 // Print content key to stdout.
std::cout << " InstallKey: key_id = "
<< wvcdm::b2a_hex(key_id) << std::endl;
std::cout << " InstallKey: content_key = "
<< wvcdm::b2a_hex(content_key) << std::endl;
std::cout << " InstallKey: key_control = "
<< wvcdm::b2a_hex(key_control_str) << std::endl;
#endif
if (LogCategoryEnabled(kLoggingDumpContentKeys)) {
LOGI((" InstallKey: key_id = " +
wvcdm::b2a_hex(key_id)).c_str());
LOGI((" InstallKey: content_key = " +
wvcdm::b2a_hex(content_key)).c_str());
LOGI((" InstallKey: key_control = " +
wvcdm::b2a_hex(key_control_str)).c_str());
}
// Key control must be supplied by license server
if (key_control.empty()) {
@@ -517,7 +512,7 @@ bool SessionContext::RefreshKey(const KeyId& key_id,
// Key control is not encrypted if key id is NULL
KeyControlBlock key_control_block(key_control);
if (!key_control_block.valid()) {
LOGD("Parse key control error.");
LOGE("Parse key control error.");
return false;
}
if ((key_control_block.control_bits() & kControlNonceEnabled) &&
@@ -533,12 +528,16 @@ bool SessionContext::RefreshKey(const KeyId& key_id,
Key* content_key = session_keys_.Find(key_id);
if (NULL == content_key) {
LOGD("Error: no matching content key.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Error: no matching content key.");
}
return false;
}
if (key_control.empty()) {
LOGD("Error: no key_control.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Error: no key_control.");
}
return false;
}
@@ -547,20 +546,28 @@ bool SessionContext::RefreshKey(const KeyId& key_id,
// Decrypt encrypted key control block
std::vector<uint8_t> control;
if (key_control_iv.empty()) {
LOGD("Key control block is NOT encrypted.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Key control block is NOT encrypted.");
}
control = key_control;
} else {
LOGD("Key control block is encrypted.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Key control block is encrypted.");
}
if (!DecryptMessage(content_key_value, key_control_iv, key_control,
&control)) {
LOGD("Error decrypting key control block.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Error decrypting key control block.");
}
return false;
}
}
KeyControlBlock key_control_block(control);
if (!key_control_block.valid()) {
LOGD("Parse key control error.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Parse key control error.");
}
return false;
}
if ((key_control_block.control_bits() & kControlNonceEnabled) &&
@@ -606,7 +613,6 @@ bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key,
size_t message_length,
const uint8_t* signature,
size_t signature_length) {
// Validate message signature
if (!ValidateMessage(message, message_length, signature, signature_length)) {
LOGE("[LoadRSAKey(): Could not verify signature]");
@@ -627,7 +633,7 @@ bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key,
rsa_key_length -= 8;
}
BIO *bio = BIO_new_mem_buf(pkcs8_rsa_key, rsa_key_length);
if( bio == NULL ) {
if ( bio == NULL ) {
LOGE("[LoadRSAKey(): Could not allocate bio buffer]");
return false;
}
@@ -663,7 +669,7 @@ bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key,
return false;
}
switch (RSA_check_key(rsa_key_)) {
case 1: // valid.
case 1: // valid.
return true;
case 0: // not valid.
LOGE("[LoadRSAKey(): rsa key not valid]");
@@ -690,7 +696,7 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
const KeyControlBlock& control = current_content_key()->control();
// Set the AES key.
if (static_cast<int>(key.size()) != AES_BLOCK_SIZE) {
LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d",key.size());
LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d", key.size());
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!(control.control_bits() & kControlAllowEncrypt)) {
@@ -709,11 +715,11 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
if ( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
LOGE("[Generic_Encrypt(): algorithm bad.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if( buffer_length % AES_BLOCK_SIZE != 0 ) {
if ( buffer_length % AES_BLOCK_SIZE != 0 ) {
LOGE("[Generic_Encrypt(): buffers size bad.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
@@ -767,11 +773,11 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
if ( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
LOGE("[Generic_Decrypt(): bad algorithm.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if( buffer_length % AES_BLOCK_SIZE != 0 ) {
if ( buffer_length % AES_BLOCK_SIZE != 0 ) {
LOGE("[Generic_Decrypt(): bad buffer size.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
@@ -875,7 +881,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if( algorithm != OEMCrypto_HMAC_SHA256 ) {
if ( algorithm != OEMCrypto_HMAC_SHA256 ) {
LOGE("[Generic_Verify(): bad algorithm.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
@@ -896,7 +902,6 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
bool SessionContext::UpdateMacKeys(const std::vector<uint8_t>& enc_mac_keys,
const std::vector<uint8_t>& iv) {
// Decrypt mac key from enc_mac_key using device_keya
std::vector<uint8_t> mac_keys;
if (!DecryptMessage(encryption_key_, iv, enc_mac_keys, &mac_keys)) {
@@ -911,12 +916,14 @@ bool SessionContext::UpdateMacKeys(const std::vector<uint8_t>& enc_mac_keys,
bool SessionContext::SelectContentKey(const KeyId& key_id) {
const Key* content_key = session_keys_.Find(key_id);
#if 0
std::cout << " Select Key: key_id = "
<< wvcdm::b2a_hex(key_id) << std::endl;
std::cout << " Select Key: key = "
<< wvcdm::b2a_hex(content_key->value()) << std::endl;
#endif
if (LogCategoryEnabled(kLoggingTraceDecryption)){
LOGI(( " Select Key: key_id = " +
wvcdm::b2a_hex(key_id) ).c_str());
LOGI(( " Select Key: key = " +
wvcdm::b2a_hex(content_key->value()) ).c_str());
}
if (NULL == content_key) {
LOGE("[SelectContentKey(): No key matches key id]");
return false;
@@ -1176,4 +1183,4 @@ void NonceTable::Flush() {
}
}
}; // namespace wvoec_mock
}; // namespace wvoec_mock

View File

@@ -5,10 +5,13 @@
#include "oemcrypto_key_mock.h"
#include <cstring>
#include <vector>
#include "log.h"
#include "oemcrypto_logging.h"
#include "wv_cdm_constants.h"
namespace wvoec_mock {
#define FOURCC(c1, c2, c3, c4) \
@@ -40,7 +43,7 @@ uint32_t KeyControlBlock::ExtractField(const std::vector<uint8_t>& str,
KeyControlBlock::KeyControlBlock(
const std::vector<uint8_t>& key_control_string) {
if (key_control_string.size() < wvcdm::KEY_CONTROL_SIZE) {
LOGE("KCB: BAD Size: %d (not %d)",key_control_string.size(),
LOGE("KCB: BAD Size: %d (not %d)", key_control_string.size(),
wvcdm::KEY_CONTROL_SIZE);
return;
}
@@ -49,49 +52,51 @@ KeyControlBlock::KeyControlBlock(
duration_ = ExtractField(key_control_string, 1);
nonce_ = ExtractField(key_control_string, 2);
control_bits_ = ExtractField(key_control_string, 3);
LOGD("KCB:");
LOGD(" valid: %d", valid());
LOGD(" duration: %d", duration());
LOGD(" nonce: %08X", nonce());
LOGD(" magic: %08X", verification());
LOGD(" bits: %08X", control_bits());
switch (control_bits() & kControlReplayMask) {
case kControlNonceRequired:
LOGD(" bits kControlReplay kControlNonceRequired.");
break;
case kControlNonceOrEntry:
LOGD(" bits kControlReplay kControlNonceOrEntry.");
break;
default:
LOGD(" bits kControlReplay unset.");
break;
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("KCB:");
LOGD(" valid: %d", valid());
LOGD(" duration: %d", duration());
LOGD(" nonce: %08X", nonce());
LOGD(" magic: %08X", verification());
LOGD(" bits: %08X", control_bits());
switch (control_bits() & kControlReplayMask) {
case kControlNonceRequired:
LOGD(" bits kControlReplay kControlNonceRequired.");
break;
case kControlNonceOrEntry:
LOGD(" bits kControlReplay kControlNonceOrEntry.");
break;
default:
LOGD(" bits kControlReplay unset.");
break;
}
LOGD(" bits kControlKDCPVersion 0x%02x.",
(control_bits() & kControlHDCPVersionMask)
>> kControlHDCPVersionShift);
LOGD(" bit kControlAllowEncrypt %s.",
(control_bits() & kControlAllowEncrypt) ? "set" : "unset");
LOGD(" bit kControlAllowDecrypt %s.",
(control_bits() & kControlAllowDecrypt) ? "set" : "unset");
LOGD(" bit kControlAllowSign %s.",
(control_bits() & kControlAllowSign) ? "set" : "unset");
LOGD(" bit kControlAllowVerify %s.",
(control_bits() & kControlAllowVerify) ? "set" : "unset");
LOGD(" bit kControlObserveDataPath %s.",
(control_bits() & kControlObserveDataPath) ? "set" : "unset");
LOGD(" bit kControlObserveHDCP %s.",
(control_bits() & kControlObserveHDCP) ? "set" : "unset");
LOGD(" bit kControlObserveCGMS %s.",
(control_bits() & kControlObserveCGMS) ? "set" : "unset");
LOGD(" bit kControlDataPathSecure %s.",
(control_bits() & kControlDataPathSecure) ? "set" : "unset");
LOGD(" bit kControlNonceEnabled %s.",
(control_bits() & kControlNonceEnabled) ? "set" : "unset");
LOGD(" bit kControlHDCPRequired %s.",
(control_bits() & kControlHDCPRequired) ? "set" : "unset");
uint32_t cgms_bits = control_bits() & 0x3;
const char* cgms_values[4] = {"free", "BAD", "once", "never"};
LOGD(" CGMS = %s", cgms_values[cgms_bits]);
}
LOGD(" bits kControlKDCPVersion 0x%02x.",
(control_bits() & kControlHDCPVersionMask) >> kControlHDCPVersionShift);
LOGD(" bit kControlAllowEncrypt %s.",
(control_bits() & kControlAllowEncrypt) ? "set" : "unset");
LOGD(" bit kControlAllowDecrypt %s.",
(control_bits() & kControlAllowDecrypt) ? "set" : "unset");
LOGD(" bit kControlAllowSign %s.",
(control_bits() & kControlAllowSign) ? "set" : "unset");
LOGD(" bit kControlAllowVerify %s.",
(control_bits() & kControlAllowVerify) ? "set" : "unset");
LOGD(" bit kControlObserveDataPath %s.",
(control_bits() & kControlObserveDataPath) ? "set" : "unset");
LOGD(" bit kControlObserveHDCP %s.",
(control_bits() & kControlObserveHDCP) ? "set" : "unset");
LOGD(" bit kControlObserveCGMS %s.",
(control_bits() & kControlObserveCGMS) ? "set" : "unset");
LOGD(" bit kControlDataPathSecure %s.",
(control_bits() & kControlDataPathSecure) ? "set" : "unset");
LOGD(" bit kControlNonceEnabled %s.",
(control_bits() & kControlNonceEnabled) ? "set" : "unset");
LOGD(" bit kControlHDCPRequired %s.",
(control_bits() & kControlHDCPRequired) ? "set" : "unset");
uint32_t cgms_bits = control_bits() & 0x3;
const char* cgms_values[4] = {"free", "BAD", "once", "never"};
LOGD(" CGMS = %s", cgms_values[cgms_bits]);
Validate();
}
@@ -102,4 +107,4 @@ void Key::UpdateDuration(const KeyControlBlock& control) {
control_.set_duration(control.duration());
}
}; // namespace wvoec_eng
}; // namespace wvoec_mock

View File

@@ -18,10 +18,10 @@ 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, // ........
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,
@@ -76,7 +76,7 @@ KeyboxError WvKeybox::Validate() {
memcpy(keybox.magic_, magic_, sizeof(keybox.magic_));
crc_computed = ntohl(wvcrc32(reinterpret_cast<uint8_t*>(&keybox),
sizeof(keybox) - 4)); // Drop last 4 bytes.
sizeof(keybox) - 4)); // Drop last 4 bytes.
if (crc_computed != *crc_stored) {
LOGE("[KEYBOX CRC problem: computed = %08x, stored = %08x]\n",
crc_computed, *crc_stored);
@@ -104,4 +104,4 @@ bool WvKeybox::InstallKeybox(const uint8_t* buffer, size_t keyBoxLength) {
return true;
}
}; // namespace wvoec_eng
}; // namespace wvoec_mock

View File

@@ -0,0 +1,109 @@
// Copyright 2014 Google Inc. All Rights Reserved.
#include "oemcrypto_logging.h"
#include <stdio.h>
namespace wvoec_mock {
int logging_category_setting = 0x00;
void SetLoggingSettings(int level, int categories) {
SetLoggingLevel(level);
TurnOffLoggingForAllCategories();
AddLoggingForCategories(categories);
}
void TurnOffLoggingForAllCategories() {
logging_category_setting = 0;
}
void SetLoggingLevel(int level){;
wvcdm::g_cutoff = static_cast<wvcdm::LogPriority>(level);
}
void SetLoggingLevel(wvcdm::LogPriority level) {
wvcdm::g_cutoff = level;
}
void AddLoggingForCategories(int categories) {
logging_category_setting |= categories;
}
void RemoveLoggingForCategories(int categories) {
logging_category_setting &= ~categories;
}
bool LogCategoryEnabled(int categories) {
return ( (logging_category_setting & categories) !=0 );
}
void dump_hex_helper(std::string& buffer, std::string name,
const uint8_t* vector, size_t length) {
buffer += name + " = ";
if (vector == NULL) {
buffer +="NULL;\n";
LOGE(buffer.c_str());
return;
}
int a, b;
char int_to_hexcar[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
for (size_t i = 0; i < length; i++) {
if (i == 0) {
buffer += "\n wvcdm::a2b_hex(\"";
} else if (i % 32 == 0) {
buffer += "\"\n \"";
}
a = vector[i] % 16;
b = (vector[i] - a) / 16;
buffer += int_to_hexcar[b];
buffer += int_to_hexcar[a];
}
buffer += "\");\n";
}
void dump_hex(std::string name, const uint8_t* vector, size_t length) {
std::string buffer="";
dump_hex_helper(buffer, name, vector, length);
LOGV(buffer.c_str());
}
void dump_array_part_helper(std::string& buffer, std::string array,
size_t index, std::string name,
const uint8_t* vector, size_t length) {
char index_str[256];
snprintf(index_str, sizeof index_str, "%zu", index);
if (vector == NULL) {
buffer += array.c_str();
buffer += "[";
buffer += index_str;
buffer += "].";
buffer += name.c_str();
buffer += " = NULL;\n";
LOGW(buffer.c_str());
return;
}
buffer += "std::string s";
buffer += index_str;
buffer+= "_";
dump_hex_helper(buffer, name, vector, length);
buffer += array.c_str();
buffer += "[";
buffer += index_str;
buffer += "]." + name + " = message_ptr + message.find(s";
buffer += index_str;
buffer += "_" + name + ".data());\n";
}
void dump_array_part(std::string array, size_t index,
std::string name, const uint8_t* vector, size_t length) {
std::string buffer ="";
dump_array_part_helper(buffer, array, index, name, vector, length);
LOGV(buffer.c_str());
}
} // namespace wvoec_mock

View File

@@ -9,23 +9,23 @@
#include <stdio.h>
#include <time.h>
#include <string>
#include <vector>
#include "log.h"
#include "oemcrypto_engine_mock.h"
#include "oemcrypto_logging.h"
#include "oemcrypto_usage_table_mock.h"
#include "openssl/cmac.h"
#include "openssl/evp.h"
#include "openssl/hmac.h"
#include "openssl/rand.h"
#include "openssl/sha.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
namespace wvoec_mock {
static CryptoEngine* crypto_engine = NULL;
// Set this to true when you are generating test vectors.
const bool trace_all_calls = false;
typedef struct {
uint8_t signature[wvcdm::MAC_KEY_SIZE];
uint8_t context[wvcdm::MAC_KEY_SIZE];
@@ -33,39 +33,10 @@ typedef struct {
uint8_t enc_rsa_key[];
} WrappedRSAKey;
static void dump_hex(std::string name, const uint8_t* vector, size_t length) {
printf("%s = ", name.c_str());
if (vector == NULL) {
printf("NULL;\n");
return;
}
for (size_t i = 0; i < length; i++) {
if (i == 0) {
printf("\n wvcdm::a2b_hex(\"");
} else if (i % 32 == 0) {
printf("\"\n \"");
}
printf("%02X", vector[i]);
}
printf("\");\n");
}
void dump_array_part(std::string array, size_t index,
std::string name, const uint8_t* vector, size_t length) {
if (vector == NULL) {
printf("%s[%zu].%s = NULL;\n", array.c_str(), index, name.c_str());
return;
}
printf("std::string s%zu_", index);
dump_hex(name, vector, length);
printf("%s[%zu].%s = message_ptr + message.find(s%zu_%s.data());\n",
array.c_str(), index, name.c_str(), index, name.c_str());
}
extern "C"
OEMCryptoResult OEMCrypto_Initialize(void) {
if (trace_all_calls) {
printf("------------------------- OEMCrypto_Initialize(void)\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("------------------------- OEMCrypto_Initialize(void)\n");
}
crypto_engine = new CryptoEngine;
@@ -74,14 +45,16 @@ OEMCryptoResult OEMCrypto_Initialize(void) {
LOGE("[OEMCrypto_Initialize(): failed]");
return OEMCrypto_ERROR_INIT_FAILED;
}
LOGD("[OEMCrypto_Initialize(): success]");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGD("[OEMCrypto_Initialize(): success]");
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult OEMCrypto_Terminate(void) {
if (trace_all_calls) {
printf("----------------- OEMCryptoResult OEMCrypto_Terminate(void)\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("----------------- OEMCryptoResult OEMCrypto_Terminate(void)\n");
}
if (!crypto_engine) {
@@ -95,31 +68,41 @@ OEMCryptoResult OEMCrypto_Terminate(void) {
delete crypto_engine;
crypto_engine = NULL;
LOGD("[OEMCrypto_Terminate(): success]");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGD("[OEMCrypto_Terminate(): success]");
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION *session)\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_OpenSession"
"(OEMCrypto_SESSION *session)\n");
}
SessionId sid = crypto_engine->CreateSession();
*session = (OEMCrypto_SESSION)sid;
LOGD("[OEMCrypto_OpenSession(): SID=%08x]", sid);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGD("[OEMCrypto_OpenSession(): SID=%08x]", sid);
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session)\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_CloseSession"
"(OEMCrypto_SESSION session)\n");
}
if (!crypto_engine->DestroySession((SessionId)session)) {
LOGD("[OEMCrypto_CloseSession(SID=%08X): failed]", session);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGD("[OEMCrypto_CloseSession(SID=%08X): failed]", session);
}
return OEMCrypto_ERROR_CLOSE_SESSION_FAILED;
} else {
LOGD("[OEMCrypto_CloseSession(SID=%08X): success]", session);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGD("[OEMCrypto_CloseSession(SID=%08X): success]", session);
}
return OEMCrypto_SUCCESS;
}
}
@@ -127,8 +110,9 @@ OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
extern "C"
OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
uint32_t* nonce) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GenerateNonce"
"(OEMCrypto_SESSION session,\n");
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
@@ -161,8 +145,8 @@ OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
}
session_ctx->AddNonce(nonce_value);
*nonce = nonce_value;
if (trace_all_calls) {
printf("nonce = %08x\n", nonce_value);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("nonce = %08x\n", nonce_value);
}
return OEMCrypto_SUCCESS;
}
@@ -173,12 +157,14 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session,
uint32_t mac_key_context_length,
const uint8_t* enc_key_context,
uint32_t enc_key_context_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GenerateDerivedKeys(\n");
dump_hex("mac_key_context", mac_key_context,
(size_t)mac_key_context_length);
dump_hex("enc_key_context", enc_key_context,
(size_t)enc_key_context_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GenerateDerivedKeys(\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("mac_key_context", mac_key_context,
(size_t)mac_key_context_length);
dump_hex("enc_key_context", enc_key_context,
(size_t)enc_key_context_length);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]");
@@ -201,13 +187,15 @@ OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session,
mac_ctx_str, enc_ctx_str)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (trace_all_calls) {
dump_hex("mac_key_server", &session_ctx->mac_key_server()[0],
session_ctx->mac_key_server().size());
dump_hex("mac_key_client", &session_ctx->mac_key_client()[0],
session_ctx->mac_key_client().size());
dump_hex("enc_key", &session_ctx->encryption_key()[0],
session_ctx->encryption_key().size());
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("mac_key_server", &session_ctx->mac_key_server()[0],
session_ctx->mac_key_server().size());
dump_hex("mac_key_client", &session_ctx->mac_key_client()[0],
session_ctx->mac_key_client().size());
dump_hex("enc_key", &session_ctx->encryption_key()[0],
session_ctx->encryption_key().size());
}
}
return OEMCrypto_SUCCESS;
}
@@ -219,9 +207,11 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
size_t message_length,
uint8_t* signature,
size_t* signature_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GenerateSignature(\n");
dump_hex("message", message, message_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GenerateSignature(\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("message", message, message_length);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
@@ -250,8 +240,10 @@ OEMCryptoResult OEMCrypto_GenerateSignature(
message_length,
signature,
signature_length)) {
if (trace_all_calls) {
dump_hex("signature", signature, *signature_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("signature", signature, *signature_length);
}
}
return OEMCrypto_SUCCESS;
}
@@ -281,29 +273,33 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
const OEMCrypto_KeyObject* key_array,
const uint8_t* pst,
size_t pst_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,\n");
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
dump_hex("enc_mac_key_iv", enc_mac_key_iv, wvcdm::KEY_IV_SIZE);
dump_hex("enc_mac_keys", enc_mac_keys, 2*wvcdm::MAC_KEY_SIZE);
dump_hex("pst", pst, pst_length);
for (size_t i = 0; i < num_keys; i++) {
printf("key_array[%zu].key_id_length=%zu;\n", i,
key_array[i].key_id_length);
dump_array_part("key_array", i, "key_id",
key_array[i].key_id, key_array[i].key_id_length);
dump_array_part("key_array", i, "key_data_iv",
key_array[i].key_data_iv, wvcdm::KEY_IV_SIZE);
dump_array_part("key_array", i, "key_data",
key_array[i].key_data, key_array[i].key_data_length);
dump_array_part("key_array", i, "key_control_iv",
key_array[i].key_control_iv, wvcdm::KEY_IV_SIZE);
dump_array_part("key_array", i, "key_control",
key_array[i].key_control, wvcdm::KEY_IV_SIZE);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
dump_hex("enc_mac_key_iv", enc_mac_key_iv, wvcdm::KEY_IV_SIZE);
dump_hex("enc_mac_keys", enc_mac_keys, 2*wvcdm::MAC_KEY_SIZE);
dump_hex("pst", pst, pst_length);
for (size_t i = 0; i < num_keys; i++) {
LOGV("key_array[%zu].key_id_length=%zu;\n", i,
key_array[i].key_id_length);
dump_array_part("key_array", i, "key_id",
key_array[i].key_id, key_array[i].key_id_length);
dump_array_part("key_array", i, "key_data_iv",
key_array[i].key_data_iv, wvcdm::KEY_IV_SIZE);
dump_array_part("key_array", i, "key_data",
key_array[i].key_data, key_array[i].key_data_length);
dump_array_part("key_array", i, "key_control_iv",
key_array[i].key_control_iv, wvcdm::KEY_IV_SIZE);
dump_array_part("key_array", i, "key_control",
key_array[i].key_control, wvcdm::KEY_IV_SIZE);
}
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_LoadKeys(): ERROR_KEYBOX_INVALID]");
return OEMCrypto_ERROR_KEYBOX_INVALID;
@@ -354,15 +350,16 @@ OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
}
extern "C"
OEMCryptoResult OEMCrypto_RefreshKeys(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
const uint8_t* signature,
size_t signature_length,
size_t num_keys,
const OEMCrypto_KeyRefreshObject* key_array) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_RefreshKeys(num_keys=%zu)\n",
OEMCryptoResult OEMCrypto_RefreshKeys(
OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
const uint8_t* signature,
size_t signature_length,
size_t num_keys,
const OEMCrypto_KeyRefreshObject* key_array) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_RefreshKeys(num_keys=%zu)\n",
num_keys);
}
@@ -415,7 +412,7 @@ OEMCryptoResult OEMCrypto_RefreshKeys(OEMCrypto_SESSION session,
key_array[i].key_id + key_array[i].key_id_length);
key_control.assign(key_array[i].key_control,
key_array[i].key_control + wvcdm::KEY_CONTROL_SIZE);
if (key_array[i].key_control_iv == NULL ) {
if ( key_array[i].key_control_iv == NULL ) {
key_control_iv.clear();
} else {
key_control_iv.assign(key_array[i].key_control_iv,
@@ -448,9 +445,12 @@ extern "C"
OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
const uint8_t* key_id,
size_t key_id_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,\n");
dump_hex("key_id", key_id, key_id_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_SelectKey"
"(const OEMCrypto_SESSION session,\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("key_id", key_id, key_id_length);
}
}
#ifndef NDEBUG
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
@@ -484,8 +484,9 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
size_t block_offset,
const OEMCrypto_DestBufferDesc* out_buffer,
uint8_t subsample_flags) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_DecryptCTR"
"(OEMCrypto_SESSION session,\n");
}
wvoec_mock::BufferType buffer_type = kBufferTypeDirect;
uint8_t* destination = NULL;
@@ -541,8 +542,8 @@ OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
extern "C"
OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
size_t keyBoxLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t *keybox,\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t *keybox,\n");
}
if (crypto_engine->keybox().InstallKeybox(keybox, keyBoxLength)) {
return OEMCrypto_SUCCESS;
@@ -552,8 +553,8 @@ OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox,
extern "C"
OEMCryptoResult OEMCrypto_IsKeyboxValid(void) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_IsKeyboxValid(void) {\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_IsKeyboxValid(void) {\n");
}
switch(crypto_engine->ValidateKeybox()) {
case NO_ERROR: return OEMCrypto_SUCCESS;
@@ -567,8 +568,8 @@ OEMCryptoResult OEMCrypto_IsKeyboxValid(void) {
extern "C"
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
size_t* idLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,\n");
}
std::vector<uint8_t> dev_id_string = crypto_engine->keybox().device_id();
if (dev_id_string.empty()) {
@@ -585,15 +586,17 @@ OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
memset(deviceID, 0, *idLength);
memcpy(deviceID, &dev_id_string[0], dev_id_len);
*idLength = dev_id_len;
LOGD("[OEMCrypto_GetDeviceId(): success]");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGD("[OEMCrypto_GetDeviceId(): success]");
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
size_t* keyDataLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,\n");
}
size_t length = crypto_engine->keybox().key_data_length();
if (*keyDataLength < length) {
@@ -604,14 +607,17 @@ OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
memset(keyData, 0, *keyDataLength);
memcpy(keyData, crypto_engine->keybox().key_data(), length);
*keyDataLength = length;
LOGD("[OEMCrypto_GetKeyData(): success]");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGD("[OEMCrypto_GetKeyData(): success]");
}
return OEMCrypto_SUCCESS;
}
extern "C"
OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, size_t dataLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, size_t dataLength) {\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GetRandom"
"(uint8_t* randomData, size_t dataLength) {\n");
}
if (!randomData) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -629,8 +635,8 @@ OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t* keybox,
size_t* wrappedKeyBoxLength,
const uint8_t* transportKey,
size_t transportKeyLength) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t *keybox,\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_WrapKeybox(const uint8_t *keybox,\n");
}
if (!keybox || !wrappedKeybox || !wrappedKeyBoxLength
|| (keyBoxLength != *wrappedKeyBoxLength)) {
@@ -654,13 +660,17 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
const uint8_t* enc_rsa_key_iv,
uint8_t* wrapped_rsa_key,
size_t* wrapped_rsa_key_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey()\n");
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
printf("nonce = %08X;\n", *nonce);
dump_hex("enc_rsa_key", enc_rsa_key, enc_rsa_key_length);
dump_hex("enc_rsa_key_iv", enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls | kLoggingTraceNonce)) {
LOGI("-- OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey()\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
}
LOGI("nonce = %08X;\n", *nonce);
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("enc_rsa_key", enc_rsa_key, enc_rsa_key_length);
dump_hex("enc_rsa_key_iv", enc_rsa_key_iv, wvcdm::KEY_IV_SIZE);
}
}
if (wrapped_rsa_key_length == NULL) {
LOGE("[OEMCrypto_RewrapDeviceRSAKey(): OEMCrypto_ERROR_INVALID_CONTEXT]");
@@ -673,7 +683,9 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey);
if (wrapped_rsa_key == NULL || *wrapped_rsa_key_length < buffer_size) {
LOGW("[OEMCrypto_RewrapDeviceRSAKey(): Wrapped Keybox Short Buffer]");
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
LOGW("[OEMCrypto_RewrapDeviceRSAKey(): Wrapped Keybox Short Buffer]");
}
*wrapped_rsa_key_length = buffer_size;
return OEMCrypto_ERROR_SHORT_BUFFER;
}
@@ -777,11 +789,13 @@ OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(OEMCrypto_SESSION session,
result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if (trace_all_calls) {
dump_hex("wrapped_rsa_key", wrapped_rsa_key, *wrapped_rsa_key_length);
dump_hex("signature", wrapped->signature, sizeof(wrapped->signature));
dump_hex("context", wrapped->context, sizeof(wrapped->context));
dump_hex("iv", wrapped->iv, sizeof(wrapped->iv));
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("wrapped_rsa_key", wrapped_rsa_key, *wrapped_rsa_key_length);
dump_hex("signature", wrapped->signature, sizeof(wrapped->signature));
dump_hex("context", wrapped->context, sizeof(wrapped->context));
dump_hex("iv", wrapped->iv, sizeof(wrapped->iv));
}
}
return result;
}
@@ -796,12 +810,14 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
}
const WrappedRSAKey* wrapped
= reinterpret_cast<const WrappedRSAKey*>(wrapped_rsa_key);
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_LoadDeviceRSAKey()\n");
dump_hex("wrapped_rsa_key", wrapped_rsa_key, wrapped_rsa_key_length);
dump_hex("signature", wrapped->signature, sizeof(wrapped->signature));
dump_hex("context", wrapped->context, sizeof(wrapped->context));
dump_hex("iv", wrapped->iv, sizeof(wrapped->iv));
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_LoadDeviceRSAKey()\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("wrapped_rsa_key", wrapped_rsa_key, wrapped_rsa_key_length);
dump_hex("signature", wrapped->signature, sizeof(wrapped->signature));
dump_hex("context", wrapped->context, sizeof(wrapped->context));
dump_hex("iv", wrapped->iv, sizeof(wrapped->iv));
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_LoadDeviceRSAKey(): ERROR_KEYBOX_INVALID]");
@@ -852,15 +868,19 @@ OEMCryptoResult OEMCrypto_LoadDeviceRSAKey(OEMCrypto_SESSION session,
}
extern "C"
OEMCryptoResult OEMCrypto_GenerateRSASignature(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length,
RSA_Padding_Scheme padding_scheme) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GenerateRSASignature()\n");
dump_hex("message", message, message_length);
OEMCryptoResult OEMCrypto_GenerateRSASignature(
OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length,
RSA_Padding_Scheme padding_scheme) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GenerateRSASignature()\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("message", message, message_length);
dump_hex("message", message, message_length);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_KEYBOX_INVALID]");
@@ -895,8 +915,10 @@ OEMCryptoResult OEMCrypto_GenerateRSASignature(OEMCrypto_SESSION session,
signature,
signature_length,
padding_scheme)) {
if (trace_all_calls) {
dump_hex("signature", signature, *signature_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("signature", signature, *signature_length);
}
}
return OEMCrypto_SUCCESS;
}
@@ -912,13 +934,15 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
size_t mac_key_context_length,
const uint8_t* enc_key_context,
size_t enc_key_context_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(\n");
dump_hex("enc_session_key", enc_session_key, enc_session_key_length);
dump_hex("mac_key_context", mac_key_context,
(size_t)mac_key_context_length);
dump_hex("enc_key_context", enc_key_context,
(size_t)enc_key_context_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("enc_session_key", enc_session_key, enc_session_key_length);
dump_hex("mac_key_context", mac_key_context,
(size_t)mac_key_context_length);
dump_hex("enc_key_context", enc_key_context,
(size_t)enc_key_context_length);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]");
@@ -947,13 +971,15 @@ OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
if (!session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str)) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (trace_all_calls) {
dump_hex("mac_key_server", &session_ctx->mac_key_server()[0],
session_ctx->mac_key_server().size());
dump_hex("mac_key", &session_ctx->mac_key_client()[0],
session_ctx->mac_key_client().size());
dump_hex("enc_key", &session_ctx->encryption_key()[0],
session_ctx->encryption_key().size());
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("mac_key_server", &session_ctx->mac_key_server()[0],
session_ctx->mac_key_server().size());
dump_hex("mac_key", &session_ctx->mac_key_client()[0],
session_ctx->mac_key_client().size());
dump_hex("enc_key", &session_ctx->encryption_key()[0],
session_ctx->encryption_key().size());
}
}
return OEMCrypto_SUCCESS;
}
@@ -969,10 +995,11 @@ const char* OEMCrypto_SecurityLevel() {
}
extern "C"
OEMCryptoResult OEMCrypto_GetHDCPCapability(OEMCrypto_HDCP_Capability *current,
OEMCrypto_HDCP_Capability *maximum) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_GetHDCPCapability(%p, %p)\n",
OEMCryptoResult OEMCrypto_GetHDCPCapability(
OEMCrypto_HDCP_Capability *current,
OEMCrypto_HDCP_Capability *maximum) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_GetHDCPCapability(%p, %p)\n",
current, maximum);
}
if (current == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
@@ -989,12 +1016,13 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session,
const uint8_t* iv,
OEMCrypto_Algorithm algorithm,
uint8_t* out_buffer) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_Generic_Encrypt( algorithm=%d\n",
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_Generic_Encrypt( algorithm=%d\n",
algorithm);
dump_hex("in_buffer", in_buffer, buffer_length);
dump_hex("iv", iv, wvcdm::KEY_IV_SIZE);
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("in_buffer", in_buffer, buffer_length);
dump_hex("iv", iv, wvcdm::KEY_IV_SIZE);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_Generic_Enrypt(): ERROR_KEYBOX_INVALID]");
@@ -1013,8 +1041,10 @@ OEMCryptoResult OEMCrypto_Generic_Encrypt(OEMCrypto_SESSION session,
OEMCryptoResult sts =
session_ctx->Generic_Encrypt(in_buffer, buffer_length, iv, algorithm,
out_buffer);
if (trace_all_calls) {
dump_hex("out_buffer", out_buffer, buffer_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("out_buffer", out_buffer, buffer_length);
}
}
return sts;
}
@@ -1026,11 +1056,13 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session,
const uint8_t* iv,
OEMCrypto_Algorithm algorithm,
uint8_t* out_buffer) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_Generic_Decrypt( algorithm=%d\n",
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_Generic_Decrypt( algorithm=%d\n",
algorithm);
dump_hex("in_buffer", in_buffer, buffer_length);
dump_hex("iv", iv, wvcdm::KEY_IV_SIZE);
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("in_buffer", in_buffer, buffer_length);
dump_hex("iv", iv, wvcdm::KEY_IV_SIZE);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_Generic_Decrypt(): ERROR_KEYBOX_INVALID]");
@@ -1049,8 +1081,10 @@ OEMCryptoResult OEMCrypto_Generic_Decrypt(OEMCrypto_SESSION session,
OEMCryptoResult sts =
session_ctx->Generic_Decrypt(in_buffer, buffer_length, iv, algorithm,
out_buffer);
if (trace_all_calls) {
dump_hex("out_buffer", out_buffer, buffer_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE){
dump_hex("out_buffer", out_buffer, buffer_length);
}
}
return sts;
}
@@ -1062,10 +1096,12 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
OEMCrypto_Algorithm algorithm,
uint8_t* signature,
size_t* signature_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_Generic_Sign( algorithm=%d\n",
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_Generic_Sign( algorithm=%d\n",
algorithm);
dump_hex("in_buffer", in_buffer, buffer_length);
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("in_buffer", in_buffer, buffer_length);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_Generic_Sign(): ERROR_KEYBOX_INVALID]");
@@ -1087,8 +1123,10 @@ OEMCryptoResult OEMCrypto_Generic_Sign(OEMCrypto_SESSION session,
OEMCryptoResult sts =
session_ctx->Generic_Sign(in_buffer, buffer_length, algorithm,
signature, signature_length);
if (trace_all_calls) {
dump_hex("signature", signature, *signature_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("signature", signature, *signature_length);
}
}
return sts;
}
@@ -1100,11 +1138,13 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session,
OEMCrypto_Algorithm algorithm,
const uint8_t* signature,
size_t signature_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_Generic_Verify( algorithm=%d\n",
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_Generic_Verify( algorithm=%d\n",
algorithm);
dump_hex("in_buffer", in_buffer, buffer_length);
dump_hex("signature", signature, signature_length);
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("in_buffer", in_buffer, buffer_length);
dump_hex("signature", signature, signature_length);
}
}
if (NO_ERROR != crypto_engine->ValidateKeybox()) {
LOGE("[OEMCrypto_Generic_Verify(): ERROR_KEYBOX_INVALID]");
@@ -1128,15 +1168,15 @@ OEMCryptoResult OEMCrypto_Generic_Verify(OEMCrypto_SESSION session,
extern "C"
bool OEMCrypto_SupportsUsageTable() {
if (trace_all_calls) {
printf("-- bool OEMCrypto_SupportsUsageTable(); // returns true.\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- bool OEMCrypto_SupportsUsageTable(); // returns true.\n");
}
return true;
}
extern "C"
OEMCryptoResult OEMCrypto_UpdateUsageTable() {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_UpdateUsageTable();\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_UpdateUsageTable();\n");
}
return crypto_engine->usage_table()->UpdateTable();
}
@@ -1144,9 +1184,11 @@ OEMCryptoResult OEMCrypto_UpdateUsageTable() {
extern "C"
OEMCryptoResult OEMCrypto_DeactivateUsageEntry(const uint8_t *pst,
size_t pst_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_DeactivateUsageEntry(\n");
dump_hex("pst", pst, pst_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_DeactivateUsageEntry(\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("pst", pst, pst_length);
}
}
std::vector<uint8_t> pstv(pst, pst + pst_length);
return crypto_engine->usage_table()->DeactivateEntry(pstv);
@@ -1158,9 +1200,11 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
size_t pst_length,
OEMCrypto_PST_Report *buffer,
size_t *buffer_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_ReportUsage(\n");
dump_hex("pst", pst, pst_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_ReportUsage(\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("pst", pst, pst_length);
}
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
@@ -1176,9 +1220,11 @@ OEMCryptoResult OEMCrypto_ReportUsage(OEMCrypto_SESSION session,
OEMCryptoResult sts =
entry->ReportUsage(session_ctx, pstv, buffer, buffer_length);
crypto_engine->usage_table()->UpdateTable();
if (trace_all_calls) {
dump_hex("usage buffer", reinterpret_cast<uint8_t*>(buffer),
*buffer_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("usage buffer", reinterpret_cast<uint8_t*>(buffer),
*buffer_length);
}
}
return sts;
}
@@ -1191,11 +1237,13 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session,
size_t message_length,
const uint8_t *signature,
size_t signature_length) {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_DeleteUsageEntry(\n");
dump_hex("pst", pst, pst_length);
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_DeleteUsageEntry(\n");
if (wvcdm::g_cutoff >= wvcdm::LOG_VERBOSE) {
dump_hex("pst", pst, pst_length);
dump_hex("message", message, message_length);
dump_hex("signature", signature, signature_length);
}
}
SessionContext* session_ctx = crypto_engine->FindSession(session);
if (!session_ctx || !session_ctx->isValid()) {
@@ -1226,8 +1274,8 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session,
extern "C"
OEMCryptoResult OEMCrypto_DeleteUsageTable() {
if (trace_all_calls) {
printf("-- OEMCryptoResult OEMCrypto_DeleteUsageTable()\n");
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
LOGI("-- OEMCryptoResult OEMCrypto_DeleteUsageTable()\n");
}
if (crypto_engine->usage_table()->Clear()) {
return OEMCrypto_SUCCESS;

View File

@@ -3,14 +3,17 @@
// Mock implementation of OEMCrypto APIs
//
#include "oemcrypto_usage_table_mock.h"
#include "oemcrypto_engine_mock.h"
#include <cstring>
#include <string>
#include <vector>
#include "clock.h"
#include "log.h"
#include "file_store.h"
#include "properties.h"
#include "oemcrypto_engine_mock.h"
#include "oemcrypto_logging.h"
#include "openssl/aes.h"
#include "openssl/rand.h"
#include "openssl/sha.h"
@@ -45,6 +48,7 @@ UsageTableEntry::UsageTableEntry(const StoredUsageEntry *buffer) {
buffer->mac_key_server + wvcdm::MAC_KEY_SIZE);
mac_key_client_.assign(buffer->mac_key_client,
buffer->mac_key_client + wvcdm::MAC_KEY_SIZE);
session_ = NULL;
}
void UsageTableEntry::SaveToBuffer(StoredUsageEntry *buffer) {
@@ -158,7 +162,9 @@ UsageTable::UsageTable(CryptoEngine *ce) {
std::string filename = path + "UsageTable.dat";
if (!file.Exists(filename)) {
LOGI("UsageTable: No saved usage table. Creating new table.");
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
LOGI("UsageTable: No saved usage table. Creating new table.");
}
return;
}
size_t file_size = file.FileSize(filename);
@@ -222,9 +228,13 @@ UsageTable::UsageTable(CryptoEngine *ce) {
file.Read(reinterpret_cast<char *>(&generation_), sizeof(int64_t));
file.Close();
if (stored_table->generation == generation_ + 1) {
LOGW("UsageTable: File is one generation old. Acceptable rollback.");
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
LOGW("UsageTable: File is one generation old. Acceptable rollback.");
}
} else if (stored_table->generation == generation_ - 1) {
LOGW("UsageTable: File is one generation new. Acceptable rollback.");
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
LOGW("UsageTable: File is one generation new. Acceptable rollback.");
}
// This might happen if the generation number was rolled back?
} else if (stored_table->generation != generation_) {
LOGE("UsageTable: Rollback detected. Clearing Usage Table. %lx -> %lx",
@@ -241,7 +251,9 @@ UsageTable::UsageTable(CryptoEngine *ce) {
new UsageTableEntry(&stored_table->entries[i].entry);
table_[entry->pst_hash()] = entry;
}
LOGI("UsageTable: loaded %d entryies.", stored_table->count);
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
LOGI("UsageTable: loaded %d entries.", stored_table->count);
}
}
bool UsageTable::SaveToFile() {
@@ -308,7 +320,9 @@ bool UsageTable::SaveToFile() {
std::string filename = path + "UsageTable.dat";
if (!file.Exists(filename)) {
LOGI("UsageTable: No saved usage table. Creating new table.");
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
LOGI("UsageTable: No saved usage table. Creating new table.");
}
}
if (!file.Open(filename, wvcdm::File::kCreate | wvcdm::File::kTruncate |

View File

@@ -0,0 +1,138 @@
// Copyright 2014 Google Inc. All Rights Reserved.
#include "OEMCryptoCENC.h"
#include <string>
#include <gtest/gtest.h>
#include "log.h"
#include "oemcrypto_logging.h"
#include "oemcrypto_mock.cpp"
class OEMCryptoLoggingTest : public ::testing::Test {
protected:
OEMCryptoLoggingTest() {}
void SetUp() {
::testing::Test::SetUp();
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
}
void TearDown() {
OEMCrypto_Terminate();
::testing::Test::TearDown();
}
};
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");
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);
ASSERT_EQ(buffer, "name = \n wvcdm::a2b_hex(\"FA112833FA112833FA112833F"
"A112833FA112833FA112833011428ABFACDEF67\"\n \""
"011428ABFACDEF67\");\n");
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 = "";
wvoec_mock::dump_array_part_helper(buffer, "array", (size_t) 5,
"name", NULL, (size_t) 40);
ASSERT_EQ(buffer, "array[5].name = NULL;\n");
}
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(2);
ASSERT_EQ(wvcdm::g_cutoff, wvcdm::LOG_INFO);
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::TurnOffLoggingForAllCategories();
wvoec_mock::SetLoggingLevel(wvcdm::LOG_VERBOSE);
ASSERT_EQ(wvcdm::g_cutoff, wvcdm::LOG_VERBOSE);
wvoec_mock::SetLoggingLevel(1);
}
namespace wvoec_mock {
TEST_F(OEMCryptoLoggingTest, TestChangeLoggingCategories) {
TurnOffLoggingForAllCategories();
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceDecryption |
kLoggingTraceOEMCryptoCalls), false);
AddLoggingForCategories(kLoggingDumpKeyControlBlocks |
kLoggingDumpDerivedKeys);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpKeyControlBlocks), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceUsageTable), false);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpTraceAll), true);
RemoveLoggingForCategories(kLoggingDumpKeyControlBlocks |
kLoggingTraceUsageTable);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpKeyControlBlocks), false);
ASSERT_EQ(LogCategoryEnabled(kLoggingDumpDerivedKeys), true);
ASSERT_EQ(LogCategoryEnabled(kLoggingTraceUsageTable), false);
TurnOffLoggingForAllCategories();
bool flag = false;
if (LogCategoryEnabled(kLoggingTraceUsageTable)) {
flag = true;
}
ASSERT_EQ(flag, false);
AddLoggingForCategories(kLoggingDumpTraceAll);
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
flag = true;
}
ASSERT_EQ(flag, true);
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);
flag= false;
RemoveLoggingForCategories(kLoggingDumpKeyControlBlocks);
if ( LogCategoryEnabled(kLoggingDumpKeyControlBlocks) ) {
flag = true;
}
ASSERT_EQ(flag, false);
}
} // namespace wvoec_mock
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
wvcdm::InitLogging(argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,109 +0,0 @@
#
# Builds oemcrypto_unittests
#
#PROJECTS_ROOT = ~projects
#
ifndef PROJECTS_ROOT
PROJECTS_ROOT = ../../../../..
endif
CDM_ROOT = $(PROJECTS_ROOT)/cdm
CDM_SRC_PATH = $(CDM_ROOT)/cdm
CDM_BASE_INCLUDE_PATH = $(CDM_SRC_PATH)/include
EUREKA_ROOT = $(PROJECTS_ROOT)/eureka/eureka
CHROME_ROOT = $(EUREKA_ROOT)/src/chromium/src
#
# build outputs should go into Chrome repository, such as ../chromium/src/out
# or some local equivalent.
# WARNING: splitting outputs from CHROME_ROOT can lead to build errors
ifndef CHROME_ROOT
CHROME_ROOT = $(CDM_ROOT)/out
endif
# TARGET_PLATFORM from {x86,eureka}
ifndef TARGET_PLATFORM
TARGET_PLATFORM = x86
endif
# TARGET_BUILD from {debug,release}
ifndef TARGET_BUILD
TARGET_BUILD = debug
endif
ifeq ($(TARGET_PLATFORM),x86)
BUILDPLATFORM = out_x86_linux
else ifeq ($(TARGET_PLATFORM),eureka)
BUILDPLATFORM = out_arm_eureka
else
BUILDPLATFORM = UNKNOWN
endif
ifeq ($(TARGET_BUILD),debug)
BUILDTYPE = Debug
else ifeq ($(TARGET_BUILD),release)
BUILDTYPE = Release
else
BUILDTYPE = UNKNOWN
endif
BUILDPATH = $(CHROME_ROOT)/$(BUILDPLATFORM)/$(BUILDTYPE)
OBJPATH = $(BUILDPATH)/obj
CHROME_THIRD_PARTY_LIBS = $(BUILDPATH)/obj/third_party
# target image file name
TARGET_TEST_EXE = oemcrypto_unittests
TARGET_OBJECTS = oemcrypto_test.o
OBJECTDIR = $(OBJPATH)/oemcrypto_unittests
INSTALLDIR = $(BUILDPATH)
LIBGTEST_INCLUDE = $(CDM_SRC_PATH)/prebuilt/gtest/include
LIBGTEST_LIBS = $(CDM_SRC_PATH)/prebuilt/gtest/$(BUILDPLATFORM)/$(BUILDTYPE)/lib
LIBGTEST_LIBNAME = gtest
INCLUDES = \
-I$(LIBGTEST_INCLUDE) \
-I$(CDM_BASE_INCLUDE_PATH)
LIBDIRS = \
-L$(INSTALLDIR) \
-L$(LIBGTEST_LIBS)
OBJECTS := $(patsubst %.o,$(OBJECTDIR)/%.o,$(TARGET_OBJECTS))
CXXFLAGS = -m64 -fPIC -W -Wall -g -DCDM_TEST
LINK = $(CXX)
MKDIR = mkdir -p
$(INSTALLDIR)/$(TARGET_TEST_EXE): $(OBJECTDIR) $(INSTALLDIR) $(OBJECTS)
$(CXX) -v -fPIC -m64 $(OBJECTS) $(LIBDIRS) -loemcrypto_mock \
-lcrypto -ldl -lrt -lpthread -l$(LIBGTEST_LIBNAME) -o $@
@echo "[Unit test image: " $(INSTALLDIR)/$(TARGET_TEST_EXE) "]"
$(OBJECTDIR)/%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@
$(OBJECTDIR)/%.o: %.cc
$(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@
clean:
$(RM) -rf $(OBJECTDIR)
$(RM) -rf $(INSTALLDIR)/$(TARGET_TEST_EXE)
$(OBJECTDIR):
@$(MKDIR) $@
$(INSTALLDIR):
@$(MKDIR) $@
.PHONY: $(OBJECTDIR)
.PHONY: $(INSTALLDIR)
.PHONY: clean
.PHONY: test

View File

@@ -89,6 +89,9 @@ struct PaddedPSTReport {
uint8_t padding[256];
};
// These are test keyboxes. They will not be accepted by production systems.
// By using known keyboxes for these tests, the results for a given set of
// inputs to a test are predictable and can be compared to the actual results.
const wvoec_mock::WidevineKeybox kDefaultKeybox = {
// Sample keybox used for test vectors
{
@@ -185,9 +188,8 @@ static wvoec_mock::WidevineKeybox kValidKeybox03 = {
}
};
/* Note: Key 1 was 3072 bits. We are only generating 2048 bit keys,
so we do not need to test with 3072 bit keys. */
// A 2048-bit test RSA Private Key
// This is used to verify the functions that manipulate RSA keys.
static const uint8_t kTestPKCS1RSAPrivateKey2_2048[] = {
0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02,
0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, 0x36, 0x60,
@@ -339,7 +341,8 @@ static const uint8_t kTestPKCS1RSAPrivateKey2_2048[] = {
0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe,
0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03 };
// 2048 bit RSA key in PKCS#8 PrivateKeyInfo
// A 2048 bit RSA key in PKCS#8 PrivateKeyInfo format
// Used to verify the functions that manipulate RSA keys.
static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = {
0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
@@ -494,6 +497,8 @@ static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = {
0x72, 0x2c, 0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18,
0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03 };
// A 2048 bit RSA Public key
// Used to verify the functions that manipulate RSA keys.
static const uint8_t kTestRSAPublicKey2_2048[] = {
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
0x00, 0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd,
@@ -530,6 +535,8 @@ static const uint8_t kTestRSAPublicKey2_2048[] = {
0x6b, 0xbb, 0xbb, 0x2c, 0x5f, 0xcf, 0xb3, 0x7a,
0x05, 0x02, 0x03, 0x01, 0x00, 0x01 };
// A second 2048-bit RSA private key
// This is used to verify the functions that manipulate RSA keys.
static const uint8_t kTestPKCS1RSAPrivateKey3_2048[] = {
0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02,
0x82, 0x01, 0x01, 0x00, 0xa5, 0xd0, 0xd7, 0x3e,
@@ -681,7 +688,8 @@ static const uint8_t kTestPKCS1RSAPrivateKey3_2048[] = {
0x98, 0x18, 0x0e, 0x65, 0xb6, 0x4b, 0x69, 0x0b,
0x21, 0xdc, 0x86, 0x17, 0x6e, 0xc8, 0xee, 0x24 };
// 2048 bit RSA key in PKCS#8 PrivateKeyInfo
// A second 2048 bit RSA key in PKCS#8 PrivateKeyInfo format
// Used to verify the functions that manipulate RSA keys.
static const uint8_t kTestRSAPKCS8PrivateKeyInfo3_2048[] = {
0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
@@ -837,6 +845,8 @@ static const uint8_t kTestRSAPKCS8PrivateKeyInfo3_2048[] = {
0x69, 0x0b, 0x21, 0xdc, 0x86, 0x17, 0x6e, 0xc8,
0xee, 0x24 };
// A second 2048 bit RSA Public key
// Used to verify the functions that manipulate RSA keys.
static const uint8_t kTestRSAPublicKey3_2048[] = {
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
0x00, 0xa5, 0xd0, 0xd7, 0x3e, 0x0e, 0x2d, 0xfb,
@@ -938,8 +948,11 @@ class Session {
void FillDefaultContext(vector<uint8_t>* mac_context,
vector<uint8_t>* enc_context) {
/* These context strings are normally created by the CDM layer above from
a license request message. */
/* Context strings
* These context strings are normally created by the CDM layer
* from a license request message.
* They are used to test MAC and ENC key generation.
*/
*mac_context = wvcdm::a2b_hex(
"41555448454e5449434154494f4e000a4c08001248000000020000101907d9ff"
"de13aa95c122678053362136bdf8408f8276e4c2d87ec52b61aa1b9f646e5873"
@@ -963,6 +976,9 @@ class Session {
OEMCrypto_GenerateDerivedKeys(session_id(), &mac_context[0],
mac_context.size(), &enc_context[0],
enc_context.size()));
// Expected MAC and ENC keys generated from context strings
// with test keybox "installed".
mac_key_server_ = wvcdm::a2b_hex(
"3CFD60254786AF350B353B4FBB700AB382558400356866BA16C256BCD8C502BF");
mac_key_client_ = wvcdm::a2b_hex(
@@ -1047,7 +1063,8 @@ class Session {
license_.keys[i].control.control_bits = htonl(control);
}
memcpy(license_.pst, pst.c_str(), min(sizeof(license_.pst), pst.length()));
// For the canned decryption content, The first key is:
// The first key for the canned decryption content.
vector<uint8_t> key = wvcdm::a2b_hex("39AD33E5719656069F9EDE9EBBA7A77D");
memcpy(license_.keys[0].key_data, &key[0], key.size());
}
@@ -1166,6 +1183,7 @@ class Session {
}
// Set up our expected input and output
// This is dummy encrypted data.
vector<uint8_t> encryptedData = wvcdm::a2b_hex(
"ec261c115f9d5cda1d5cc7d33c4e37362d1397c89efdd1da5f0065c4848b0462"
"337ba14693735203c9b4184e362439c0cea5e5d1a628425eddf8a6bf9ba901ca"
@@ -1177,6 +1195,7 @@ class Session {
"fc14a9ab9647e6e31adabb72d792f0c9ba99dc3e9205657d28fc7771d64e6d4b");
vector<uint8_t> encryptionIv =
wvcdm::a2b_hex("719dbcb253b2ec702bb8c1b1bc2f3bc6");
// This is the expected decrypted data.
vector<uint8_t> unencryptedData = wvcdm::a2b_hex(
"19ef4361e16e6825b336e2012ad8ffc9ce176ab2256e1b98aa15b7877bd8c626"
"fa40b2e88373457cbcf4f1b4b9793434a8ac03a708f85974cff01bddcbdd7a8e"
@@ -1231,6 +1250,7 @@ class Session {
rsa_key_length = sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048);
}
// Dummy context for testing signature generation.
vector<uint8_t> context = wvcdm::a2b_hex(
"0a4c08001248000000020000101907d9ffde13aa95c122678053362136bdf840"
"8f8276e4c2d87ec52b61aa1b9f646e58734930acebe899b3e464189a14a87202"
@@ -1426,6 +1446,8 @@ class Session {
&mac_context[0], mac_context.size(), &enc_context[0],
enc_context.size()));
// Expected MAC and ENC keys generated from context strings
// with RSA certificate "installed".
mac_key_server_ = wvcdm::a2b_hex(
"1E451E59CB663DA1646194DD28880788ED8ED2EFF913CBD6A0D535D1D5A90381");
mac_key_client_ = wvcdm::a2b_hex(
@@ -1815,7 +1837,7 @@ class DISABLED_TestKeybox : public OEMCryptoClientTest {
}
};
TEST_F(DISABLED_TestKeybox, CheckSystemID) {
TEST_F(OEMCryptoClientTest, DISABLED_CheckSystemID) {
OEMCryptoResult sts;
uint8_t key_data[256];
size_t key_data_len = sizeof(key_data);
@@ -1862,6 +1884,7 @@ 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) {
@@ -1871,6 +1894,7 @@ 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) {
@@ -1880,6 +1904,7 @@ 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) {
@@ -1889,6 +1914,7 @@ TEST_F(DISABLED_TestKeybox, GenerateSignature) {
s.GenerateDerivedKeys();
// Dummy context for testing signature generation.
vector<uint8_t> context = wvcdm::a2b_hex(
"0a4c08001248000000020000101907d9ffde13aa95c122678053362136bdf840"
"8f8276e4c2d87ec52b61aa1b9f646e58734930acebe899b3e464189a14a87202"
@@ -2354,6 +2380,7 @@ TEST_F(DISABLED_TestKeybox, DecryptWithOffset) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
// Set up our expected input and output
// This is dummy encrypted data.
vector<uint8_t> encryptedData = wvcdm::a2b_hex(
"c17055d4e3ab8e892b40ca2deed7cd46b406cd41d50f23d5877b36"
"ad351887df2b3774dc413904afd958ba766cc6ab51a3ffd8f845296c5d8326ee"
@@ -2365,6 +2392,7 @@ TEST_F(DISABLED_TestKeybox, DecryptWithOffset) {
"4bcc7bd14746304fea100dc6465ab51241355bb19e6c2cfb2bb6bbf709765d13");
vector<uint8_t> encryptionIv = wvcdm::a2b_hex(
"c09454479a280829c946df3c22f25539");
// This is the expected decrypted data.
vector<uint8_t> unencryptedData = wvcdm::a2b_hex(
"f344d9cfe336c94cf4e3ea9e3446d1427bc02d2debe6dec5b272b8"
"a4004b696c4b37e01d7418510abf32bb071f9a4bc0d2ad7e874b648e50bd0e4f"
@@ -2450,6 +2478,7 @@ TEST_F(DISABLED_TestKeybox, DecryptWithNearWrap) {
vector<uint8_t> key = wvcdm::a2b_hex("39AD33E5719656069F9EDE9EBBA7A77D");
vector<uint8_t> encryptionIv = wvcdm::a2b_hex(
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE");
// This is dummy decrypted data.
vector<uint8_t> unencryptedData = wvcdm::a2b_hex(
"f344d9cfe336c94cf4e3ea9e3446d1427bc02d2debe6dec5b272b8"
"a4004b696c4b37e01d7418510abf32bb071f9a4bc0d2ad7e874b648e50bd0e4f"
@@ -2497,6 +2526,7 @@ TEST_F(DISABLED_TestKeybox, DecryptUnencrypted) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
// Set up our expected input and output
// This is dummy decrypted data.
vector<uint8_t> unencryptedData = wvcdm::a2b_hex(
"1558497b6d994be343ed1c6d6313e0537b843e9a9c0836d1e83fe33154191ce9"
"a14d8d95bebaddc03bd471827170f527c0a166b9068b273d1bc57fbb13975ee4"
@@ -2535,6 +2565,7 @@ TEST_F(DISABLED_TestKeybox, DecryptUnencryptedNoKey) {
// CLear data should be copied even if there is no key selected.
// Set up our expected input and output
// This is dummy decrypted data.
vector<uint8_t> unencryptedData = wvcdm::a2b_hex(
"1558497b6d994be343ed1c6d6313e0537b843e9a9c0836d1e83fe33154191ce9"
"a14d8d95bebaddc03bd471827170f527c0a166b9068b273d1bc57fbb13975ee4"
@@ -4597,6 +4628,85 @@ TEST_P(DISABLED_UsageTableTest, EmptyTable) {
}
}
TEST_P(DISABLED_UsageTableTest, FiftyEntries) {
if (OEMCrypto_SupportsUsageTable()) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
Session s1;
s1.open();
s1.GenerateDerivedKeys();
std::string pst1 = "pst saved";
s1.FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
s1.get_nonce(), pst1);
s1.EncryptAndSign();
s1.LoadTestKeys(pst1, new_mac_keys_);
sleep(kShortSleep);
cout << "Making 49\n";
const size_t ENTRY_COUNT = 49;// API says should hold at least 50 entries.
Session sessions[ENTRY_COUNT];
for (int i=0; i<ENTRY_COUNT; i++) {
sessions[i].open();
sessions[i].GenerateDerivedKeys();
std::string pst = "pst ";
char c = 'A' + i;
pst = pst + c;
sessions[i].FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
sessions[i].get_nonce(), pst);
sessions[i].EncryptAndSign();
sessions[i].LoadTestKeys(pst, new_mac_keys_);
sessions[i].GenerateReport(pst);
sessions[i].close();
}
cout << "Checking 49\n";
for (int i=0; i<ENTRY_COUNT; i++) {
Session s;
s.open();
std::string pst = "pst ";
char c = 'A' + i;
pst = pst + c;
s.GenerateReport(pst, true, &sessions[i]);
EXPECT_EQ(kUnused, s.pst_report()->status);
s.close();
}
sleep(kShortSleep);
cout << "Making another 49\n";
// If I add too many entries, it can delete the older ones first, except
// it shouldn't delete the one attached to an open session. (s1)
for (int i=0; i<ENTRY_COUNT; i++) {
sessions[i].open();
sessions[i].GenerateDerivedKeys();
std::string pst = "newer pst ";
char c = 'A' + i;
pst = pst + c;
sessions[i].FillSimpleMessage(
0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired,
sessions[i].get_nonce(), pst);
sessions[i].EncryptAndSign();
sessions[i].LoadTestKeys(pst, new_mac_keys_);
sessions[i].GenerateReport(pst);
sessions[i].close();
}
cout << "Checking another 49\n";
for (int i=0; i<49; i++) {
Session s;
s.open();
std::string pst = "newer pst ";
char c = 'A' + i;
pst = pst + c;
s.GenerateReport(pst, true, &sessions[i]);
EXPECT_EQ(kUnused, s.pst_report()->status);
s.close();
}
s1.close();
s1.open(); // Make sure s1's entry is still in the table.
s1.GenerateReport(pst1);
EXPECT_EQ(kUnused, s1.pst_report()->status);
s1.close();
}
}
TEST_P(DISABLED_UsageTableTest, DeleteUnusedEntry) {
if (OEMCrypto_SupportsUsageTable()) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());
@@ -5157,21 +5267,24 @@ TEST_P(DISABLED_UsageTableTest, TimingTest) {
Session s1;
Session s2;
Session s3;
time_t loaded = time(NULL);
LoadOfflineLicense(s1, pst1);
time_t loaded1 = time(NULL);
LoadOfflineLicense(s2, pst2);
time_t loaded2 = time(NULL);
LoadOfflineLicense(s3, pst3);
time_t loaded3 = time(NULL);
sleep(kLongSleep);
time_t first_decrypt = time(NULL);
s1.open();
s1.GenerateDerivedKeys();
s1.LoadTestKeys(pst1, new_mac_keys_);
time_t first_decrypt1 = time(NULL);
s1.TestDecryptCTR();
s2.open();
s2.GenerateDerivedKeys();
s2.LoadTestKeys(pst2, new_mac_keys_);
time_t first_decrypt2 = time(NULL);
s2.TestDecryptCTR();
sleep(kLongSleep);
@@ -5204,34 +5317,36 @@ TEST_P(DISABLED_UsageTableTest, TimingTest) {
s2.open();
s3.open();
sleep(kLongSleep);
time_t report_generated = time(NULL);
time_t report_generated1 = time(NULL);
s1.GenerateReport(pst1);
time_t report_generated2 = time(NULL);
s2.GenerateReport(pst2);
time_t report_generated3 = time(NULL);
s3.GenerateReport(pst3);
EXPECT_EQ(kInactive, s1.pst_report()->status);
EXPECT_ALMOST(
report_generated - loaded,
report_generated1 - loaded1,
wvcdm::htonll64(s1.pst_report()->seconds_since_license_received));
EXPECT_ALMOST(
report_generated - first_decrypt,
report_generated1 - first_decrypt1,
wvcdm::htonll64(s1.pst_report()->seconds_since_first_decrypt));
EXPECT_ALMOST(report_generated - second_decrypt,
EXPECT_ALMOST(report_generated1 - second_decrypt,
wvcdm::htonll64(s1.pst_report()->seconds_since_last_decrypt));
EXPECT_EQ(kActive, s2.pst_report()->status);
EXPECT_ALMOST(
report_generated - loaded,
report_generated2 - loaded2,
wvcdm::htonll64(s2.pst_report()->seconds_since_license_received));
EXPECT_ALMOST(
report_generated - first_decrypt,
report_generated2 - first_decrypt2,
wvcdm::htonll64(s2.pst_report()->seconds_since_first_decrypt));
EXPECT_ALMOST(report_generated - third_decrypt,
EXPECT_ALMOST(report_generated2 - third_decrypt,
wvcdm::htonll64(s2.pst_report()->seconds_since_last_decrypt));
EXPECT_EQ(kUnused, s3.pst_report()->status);
EXPECT_ALMOST(
report_generated - loaded,
report_generated3 - loaded3,
wvcdm::htonll64(s3.pst_report()->seconds_since_license_received));
// We don't expect first or last decrypt for unused report.
}