Merge from Widevine repo of http://go/wvgerrit/121950 Remove term "Master" from "Widevine Master License Agreement". Bug: 168562298 Change-Id: I655babf1bc447f4872f6a0f849107262be42df7a
130 lines
3.9 KiB
C++
130 lines
3.9 KiB
C++
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine
|
|
// License Agreement.
|
|
//
|
|
// Reference implementation of OEMCrypto APIs
|
|
//
|
|
#include "oemcrypto_keybox_ref.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
#include "log.h"
|
|
#include "oemcrypto_types.h"
|
|
#include "platform.h"
|
|
#include "wvcrc32.h"
|
|
|
|
namespace wvoec_ref {
|
|
namespace {
|
|
constexpr size_t kKeyboxSize = 128;
|
|
constexpr size_t kDeviceIdSize = 32;
|
|
constexpr size_t kKeyDataSize = 72;
|
|
constexpr size_t kMagicOffset = 120;
|
|
const uint8_t kMagic[4] = {'k', 'b', 'o', 'x'};
|
|
constexpr size_t kCrcKeyboxSize = 124;
|
|
constexpr size_t kCrcOffset = 124;
|
|
|
|
static_assert(sizeof(wvoec::WidevineKeybox) == kKeyboxSize,
|
|
"Unexpected keybox size");
|
|
|
|
template <size_t N>
|
|
std::vector<uint8_t> ToVector(const uint8_t (&field)[N]) {
|
|
return std::vector<uint8_t>(field, &field[N]);
|
|
}
|
|
} // namespace
|
|
|
|
// static
|
|
OEMCryptoResult WvKeybox::ValidateData(const uint8_t* keybox,
|
|
size_t keybox_length) {
|
|
if (keybox == nullptr) {
|
|
LOGE("Keybox data buffer is null");
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
if (keybox_length != kKeyboxSize) {
|
|
LOGE("Invalid keybox length: length = %zu", keybox_length);
|
|
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
|
}
|
|
if (memcmp(&keybox[kMagicOffset], kMagic, sizeof(kMagic))) {
|
|
LOGE("Invalid keybox magic");
|
|
return OEMCrypto_ERROR_BAD_MAGIC;
|
|
}
|
|
uint32_t crc_provided;
|
|
memcpy(&crc_provided, &keybox[kCrcOffset], sizeof(crc_provided));
|
|
const uint32_t crc_computed = wvcrc32n(keybox, kCrcKeyboxSize);
|
|
if (crc_provided != crc_computed) {
|
|
LOGE("Invalid keybox CRC: provided = %08x, computed = %08x", crc_provided,
|
|
crc_computed);
|
|
return OEMCrypto_ERROR_BAD_CRC;
|
|
}
|
|
return OEMCrypto_SUCCESS;
|
|
}
|
|
|
|
// static
|
|
std::unique_ptr<WvKeybox> WvKeybox::Create(const uint8_t* keybox_data,
|
|
size_t keybox_length) {
|
|
std::unique_ptr<WvKeybox> keybox;
|
|
if (keybox_length != kKeyboxSize) {
|
|
LOGE("Invalid keybox length: length = %zu", keybox_length);
|
|
return keybox;
|
|
}
|
|
keybox.reset(new WvKeybox());
|
|
memcpy(reinterpret_cast<uint8_t*>(&keybox->raw_keybox_), keybox_data,
|
|
kKeyboxSize);
|
|
return keybox;
|
|
}
|
|
|
|
OEMCryptoResult WvKeybox::GetDeviceId(uint8_t* device_id,
|
|
size_t* device_id_length) const {
|
|
if (device_id_length == nullptr) {
|
|
LOGE("Output device ID length buffer is null");
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
if (device_id == nullptr && *device_id_length > 0) {
|
|
LOGE("Output device ID buffer is null");
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
if (*device_id_length < kDeviceIdSize) {
|
|
*device_id_length = kDeviceIdSize;
|
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
|
}
|
|
*device_id_length = kDeviceIdSize;
|
|
memcpy(device_id, raw_keybox_.device_id_, kDeviceIdSize);
|
|
return OEMCrypto_SUCCESS;
|
|
}
|
|
|
|
std::vector<uint8_t> WvKeybox::DeviceId() const {
|
|
return ToVector(raw_keybox_.device_id_);
|
|
}
|
|
|
|
std::vector<uint8_t> WvKeybox::DeviceKey() const {
|
|
return ToVector(raw_keybox_.device_key_);
|
|
}
|
|
|
|
OEMCryptoResult WvKeybox::GetKeyData(uint8_t* key_data,
|
|
size_t* key_data_length) const {
|
|
if (key_data_length == nullptr) {
|
|
LOGE("Output key data length buffer is null");
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
if (key_data == nullptr && *key_data_length > 0) {
|
|
LOGE("Output key data buffer is null");
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
if (*key_data_length < kKeyDataSize) {
|
|
*key_data_length = kKeyDataSize;
|
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
|
}
|
|
*key_data_length = kKeyDataSize;
|
|
memcpy(key_data, raw_keybox_.data_, kKeyDataSize);
|
|
return OEMCrypto_SUCCESS;
|
|
}
|
|
|
|
OEMCryptoResult WvKeybox::IsKeyboxValid() const {
|
|
return ValidateData(reinterpret_cast<const uint8_t*>(&raw_keybox_),
|
|
kKeyboxSize);
|
|
}
|
|
|
|
} // namespace wvoec_ref
|