Files
android/libwvdrmengine/oemcrypto/mock/src/oemcrypto_key_mock.cpp
Fred Gylys-Colwell 42f7458cfc Fix Memory Leak In OEMCrypto Level 3 Haystack
Merge from Widevine repo of http://go/wvgerrit/10308

There was a memory leak in the oemcrypto RSA code.

Also, when saving the usage table, some session variables were
allocated twice.  This results in session data  being lost.

There were also some leaks and uninitialized values in oemcrypto_test.

I added some checks and profiling to the debug runtime for the
haystack.  It will warn if a variable is left unencrypted or is
unencrypted twice.  I also added the profile code.

Versions of L3 library:
android/level3/arm/libwvlevel3.a  Level3 Library Apr  1 2015 11:40:06
android/level3/x86/libwvlevel3.a  Level3 Library Apr  1 2015 12:44:32

b/19950814

Change-Id: Ic752e36c09fce121dcaf92f9209591e74f3eb070
2015-04-01 12:52:29 -07:00

109 lines
3.9 KiB
C++

// Copyright 2013 Google Inc. All Rights Reserved.
//
// Mock implementation of OEMCrypto APIs
//
#include "oemcrypto_key_mock.h"
#include <string.h>
#include <vector>
#include "log.h"
#include "oemcrypto_logging.h"
#include "wv_cdm_constants.h"
namespace wvoec_mock {
bool KeyControlBlock::Validate() {
if (memcmp(verification_, "kctl", 4) && // original verification
memcmp(verification_, "kc09", 4) && // add in version 9 api
memcmp(verification_, "kc10", 4)) { // add in version 10 api
LOGE("KCB: BAD verification string: %4.4s", verification_);
valid_ = false;
} else {
valid_ = true;
}
return valid_;
}
// This extracts 4 bytes in network byte order to a 32 bit integer in
// host byte order.
uint32_t KeyControlBlock::ExtractField(const std::vector<uint8_t>& str,
int idx) {
int bidx = idx * 4;
uint32_t t = static_cast<unsigned char>(str[bidx]) << 24;
t |= static_cast<unsigned char>(str[bidx + 1]) << 16;
t |= static_cast<unsigned char>(str[bidx + 2]) << 8;
t |= static_cast<unsigned char>(str[bidx + 3]);
return t;
}
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(),
wvcdm::KEY_CONTROL_SIZE);
return;
}
memcpy(verification_, &key_control_string[0], 4);
duration_ = ExtractField(key_control_string, 1);
nonce_ = ExtractField(key_control_string, 2);
control_bits_ = ExtractField(key_control_string, 3);
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]);
}
Validate();
}
Key::Key(const std::vector<uint8_t>& key_string, const KeyControlBlock& control)
: value_(key_string), control_(control) {}
void Key::UpdateDuration(const KeyControlBlock& control) {
control_.set_duration(control.duration());
}
} // namespace wvoec_mock