[DO NOT MERGE] Revert "Restructed reference root of trust (1/3 Keybox)"
This reverts commit e4ee4eb404.
Reason for revert: Feature missed deadline
Bug: 135283522
Change-Id: I4ee2caac2dadfcc3e145b9c9b977d216d4edd929
This commit is contained in:
@@ -6,20 +6,14 @@
|
|||||||
//
|
//
|
||||||
#include "oemcrypto_auth_ref.h"
|
#include "oemcrypto_auth_ref.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "oemcrypto_rsa_key_shared.h"
|
||||||
|
|
||||||
namespace wvoec_ref {
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Fake device ID which is to be returned inplace of a real ID.
|
|
||||||
const std::string kFakeDeviceId = "device_with_no_keybox";
|
|
||||||
|
|
||||||
// A 2048 bit RSA key in PKCS#8 PrivateKeyInfo format
|
// A 2048 bit RSA key in PKCS#8 PrivateKeyInfo format
|
||||||
// This is the RSA Test Key. This key is not derived
|
// This is the RSA Test Key. This key is not derived
|
||||||
// from any Widevine authentication root.
|
// from any Widevine authentication root.
|
||||||
@@ -178,240 +172,32 @@ static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = {
|
|||||||
0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03
|
0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03
|
||||||
};
|
};
|
||||||
|
|
||||||
// Filler for returning vector references.
|
|
||||||
const std::vector<uint8_t> kEmptyVector;
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) {
|
namespace wvoec_ref {
|
||||||
if (prov_method_ != OEMCrypto_ProvisioningError) {
|
|
||||||
// If provisioning method is something other than ProvisioningError
|
AuthenticationRoot::AuthenticationRoot(OEMCrypto_ProvisioningMethod method) :
|
||||||
// indicates it has already been initialized before. Must
|
provisioning_method_(method),
|
||||||
// existing data.
|
use_test_keybox_(false) {
|
||||||
rsa_key_set_ = false;
|
if ((provisioning_method_ == OEMCrypto_DrmCertificate) &&
|
||||||
rsa_key_.reset();
|
!rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize)) {
|
||||||
test_rsa_key_.reset();
|
// This error message is OK in unit tests which use test certificate.
|
||||||
keybox_.reset();
|
LOGE("FATAL ERROR: Platform uses a baked-in certificate instead of a "
|
||||||
test_keybox_.reset();
|
"keybox, but the certificate could not be loaded.");
|
||||||
}
|
|
||||||
prov_method_ = method;
|
|
||||||
switch (method) {
|
|
||||||
case OEMCrypto_DrmCertificate: {
|
|
||||||
rsa_key_set_ = rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize);
|
|
||||||
if (!rsa_key_set_) {
|
|
||||||
// This error message is OK in unit tests which use test certificate.
|
|
||||||
LOGE(
|
|
||||||
"FATAL ERROR: Platform uses a baked-in certificate instead of a "
|
|
||||||
"keybox, but the certificate could not be loaded.");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case OEMCrypto_Keybox:
|
|
||||||
case OEMCrypto_OEMCertificate:
|
|
||||||
// Nothing to do yet.
|
|
||||||
return true;
|
|
||||||
case OEMCrypto_ProvisioningError:
|
|
||||||
default: {
|
|
||||||
LOGE("Invalid provisioning method: method = %d",
|
|
||||||
static_cast<int>(method));
|
|
||||||
prov_method_ = OEMCrypto_ProvisioningError;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthenticationRoot::IsValid() const {
|
KeyboxError AuthenticationRoot::ValidateKeybox() {
|
||||||
switch (prov_method_) {
|
return keybox().Validate();
|
||||||
case OEMCrypto_DrmCertificate: {
|
|
||||||
return rsa_key_set_ && HasDeviceKey();
|
|
||||||
}
|
|
||||||
case OEMCrypto_Keybox: {
|
|
||||||
return HasDeviceKey();
|
|
||||||
}
|
|
||||||
case OEMCrypto_OEMCertificate: {
|
|
||||||
// TODO(sigquit): Add OEM Certificate validation.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
LOGE("Root of trust is not properly initialized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::IsKeyboxOrOemCertValid() const {
|
bool AuthenticationRoot::LoadTestRsaKey() {
|
||||||
switch (prov_method_) {
|
return rsa_key_.LoadPkcs8RsaKey(kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||||
case OEMCrypto_Keybox: {
|
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
||||||
WvKeybox* kb = keybox();
|
|
||||||
if (kb == nullptr) {
|
|
||||||
LOGW("Null keybox cannot be validated");
|
|
||||||
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
|
||||||
}
|
|
||||||
return kb->IsKeyboxValid();
|
|
||||||
}
|
|
||||||
case OEMCrypto_OEMCertificate: {
|
|
||||||
LOGW("OEM certificate validation is not implemented");
|
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
case OEMCrypto_DrmCertificate: {
|
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
LOGE("Root of trust is not properly initialized");
|
|
||||||
return OEMCrypto_ERROR_SYSTEM_INVALIDATED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::GetDeviceId(
|
bool AuthenticationRoot::Validate() {
|
||||||
uint8_t* device_id, size_t* device_id_length) const {
|
return NO_ERROR == ValidateKeybox();
|
||||||
WvKeybox* kb = keybox();
|
|
||||||
if (kb != nullptr) {
|
|
||||||
return kb->GetDeviceId(device_id, device_id_length);
|
|
||||||
}
|
|
||||||
if (prov_method_ == OEMCrypto_Keybox) {
|
|
||||||
// Keybox devices must have keybox for the source of the device
|
|
||||||
// ID.
|
|
||||||
LOGE("Expected keybox to be set for a device ID");
|
|
||||||
return OEMCrypto_ERROR_NO_DEVICEID;
|
|
||||||
}
|
|
||||||
// For non-Keybox devices use fake device ID.
|
|
||||||
if (device_id_length == nullptr) {
|
|
||||||
LOGE("Output device ID length 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 < kFakeDeviceId.size()) {
|
|
||||||
*device_id_length = kFakeDeviceId.size();
|
|
||||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
|
||||||
}
|
|
||||||
*device_id_length = kFakeDeviceId.size();
|
|
||||||
memcpy(device_id, kFakeDeviceId.data(), kFakeDeviceId.size());
|
|
||||||
return OEMCrypto_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> AuthenticationRoot::DeviceId() const {
|
|
||||||
WvKeybox* kb = keybox();
|
|
||||||
if (kb != nullptr) {
|
|
||||||
return kb->DeviceId();
|
|
||||||
}
|
|
||||||
if (prov_method_ == OEMCrypto_Keybox) {
|
|
||||||
LOGE("Expected keybox to be set for a device ID");
|
|
||||||
return kEmptyVector;
|
|
||||||
}
|
|
||||||
return std::vector<uint8_t>(kFakeDeviceId.begin(), kFakeDeviceId.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> AuthenticationRoot::DeviceKey() const {
|
|
||||||
WvKeybox* kb = keybox();
|
|
||||||
if (kb != nullptr) {
|
|
||||||
return kb->DeviceKey();
|
|
||||||
}
|
|
||||||
LOGE("No device key has been set");
|
|
||||||
return kEmptyVector;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AuthenticationRoot::HasDeviceKey() const { return keybox() != nullptr; }
|
|
||||||
|
|
||||||
void AuthenticationRoot::Clear() {
|
|
||||||
RemoveTestRsaKey();
|
|
||||||
RemoveTestKeybox();
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::LoadTestRsaKey() {
|
|
||||||
if (prov_method_ != OEMCrypto_DrmCertificate) {
|
|
||||||
LOGE("System does not support DRM certificates");
|
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
if (test_rsa_key_.get() != nullptr) {
|
|
||||||
LOGE("Test RSA key is already loaded");
|
|
||||||
return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
if (!test_rsa_key_.LoadPkcs8RsaKey(
|
|
||||||
kTestRSAPKCS8PrivateKeyInfo2_2048,
|
|
||||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048))) {
|
|
||||||
LOGE("Failed to load test RSA key");
|
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
|
||||||
}
|
|
||||||
rsa_key_set_ = true;
|
|
||||||
return OEMCrypto_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::IsKeyboxValid() const {
|
|
||||||
WvKeybox* kb = keybox();
|
|
||||||
if (kb == nullptr) {
|
|
||||||
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
|
||||||
}
|
|
||||||
return kb->IsKeyboxValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::InstallKeybox(const uint8_t* keybox_data,
|
|
||||||
size_t keybox_length) {
|
|
||||||
if (keybox_) {
|
|
||||||
LOGE("Keybox already installed");
|
|
||||||
return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
const OEMCryptoResult result =
|
|
||||||
WvKeybox::ValidateData(keybox_data, keybox_length);
|
|
||||||
if (result != OEMCrypto_SUCCESS) {
|
|
||||||
LOGE("Cannot install an invalid keybox");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
keybox_ = WvKeybox::Create(keybox_data, keybox_length);
|
|
||||||
return OEMCrypto_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::InstallTestKeybox(
|
|
||||||
const uint8_t* keybox_data, size_t keybox_length) {
|
|
||||||
if (prov_method_ != OEMCrypto_Keybox) {
|
|
||||||
LOGE("System does not support keybox");
|
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
if (test_keybox_) {
|
|
||||||
LOGE("Test keybox already installed");
|
|
||||||
return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
const OEMCryptoResult result =
|
|
||||||
WvKeybox::ValidateData(keybox_data, keybox_length);
|
|
||||||
if (result != OEMCrypto_SUCCESS) {
|
|
||||||
LOGE("Cannot install an invalid test keybox");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
test_keybox_ = WvKeybox::Create(keybox_data, keybox_length);
|
|
||||||
return OEMCrypto_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::GetKeyData(uint8_t* key_data,
|
|
||||||
size_t* key_data_length) const {
|
|
||||||
if (prov_method_ != OEMCrypto_Keybox) {
|
|
||||||
LOGE("System does not support keybox");
|
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
WvKeybox* kb = keybox();
|
|
||||||
if (kb == nullptr) {
|
|
||||||
LOGE("No keybox to be set for source of key data");
|
|
||||||
return OEMCrypto_ERROR_NO_KEYDATA;
|
|
||||||
}
|
|
||||||
return kb->GetKeyData(key_data, key_data_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
OEMCryptoResult AuthenticationRoot::GetOemPublicCertificate(
|
|
||||||
uint8_t* public_cert, size_t* public_cert_length) const {
|
|
||||||
if (prov_method_ != OEMCrypto_OEMCertificate) {
|
|
||||||
LOGE("System does not support OEM certificates");
|
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
LOGE("OEM certificates have not been implemented on auth root");
|
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<uint8_t>& AuthenticationRoot::GetOemPrivateKey() const {
|
|
||||||
if (prov_method_ != OEMCrypto_OEMCertificate) {
|
|
||||||
LOGE("System does not support OEM certificates");
|
|
||||||
return kEmptyVector;
|
|
||||||
}
|
|
||||||
LOGE("OEM certificates have not been implemented on auth root");
|
|
||||||
return kEmptyVector;
|
|
||||||
}
|
|
||||||
} // namespace wvoec_ref
|
} // namespace wvoec_ref
|
||||||
|
|||||||
@@ -21,141 +21,61 @@
|
|||||||
#include "oemcrypto_types.h"
|
#include "oemcrypto_types.h"
|
||||||
|
|
||||||
namespace wvoec_ref {
|
namespace wvoec_ref {
|
||||||
// The AuthenticationRoot class contains the OEMCrypto information
|
|
||||||
// which makes up the "root of trust" of a device.
|
|
||||||
class AuthenticationRoot {
|
class AuthenticationRoot {
|
||||||
public:
|
public:
|
||||||
AuthenticationRoot() {}
|
explicit AuthenticationRoot(OEMCrypto_ProvisioningMethod method);
|
||||||
~AuthenticationRoot() {}
|
~AuthenticationRoot() {}
|
||||||
|
|
||||||
// Initializes the root of authentication for the provided
|
bool Validate();
|
||||||
// |method|. This will clear any previously initialied data.
|
|
||||||
bool Initialize(OEMCrypto_ProvisioningMethod method);
|
|
||||||
|
|
||||||
// General root of trust API.
|
KeyboxError ValidateKeybox();
|
||||||
|
|
||||||
// Checks that the auth root has been properly initialized and can
|
bool InstallKeybox(const uint8_t* keybox_data, size_t keybox_length) {
|
||||||
// be used by the rest of OEMCrypto for the current provisioning
|
return keybox().InstallKeybox(keybox_data, keybox_length);
|
||||||
// method.
|
|
||||||
bool IsValid() const;
|
|
||||||
|
|
||||||
// Checks the validity of the underlying Keybox or OEM Certificate
|
|
||||||
// depending on the provisioning method.
|
|
||||||
// Similar to the expected behavior of OEMCrypto_IsKeyboxOrOEMCertValid().
|
|
||||||
OEMCryptoResult IsKeyboxOrOemCertValid() const;
|
|
||||||
|
|
||||||
// Gets the device ID from the root of trust.
|
|
||||||
// Similar to the expected behavior of OEMCrypto_GetDeviceID().
|
|
||||||
OEMCryptoResult GetDeviceId(uint8_t* device_id,
|
|
||||||
size_t* device_id_length) const;
|
|
||||||
|
|
||||||
// Returns the device ID from the root of trust. Intended to be used
|
|
||||||
// for core message generation.
|
|
||||||
std::vector<uint8_t> DeviceId() const;
|
|
||||||
|
|
||||||
// Returns the device key from the root of trust. For keybox-based
|
|
||||||
// devices, this is the device key from the keybox (or test keybox
|
|
||||||
// if installed). For devices that use a non-keybox provisioning
|
|
||||||
// method, this will be a device specific key.
|
|
||||||
std::vector<uint8_t> DeviceKey() const;
|
|
||||||
|
|
||||||
// Check for the existence of a device key.
|
|
||||||
bool HasDeviceKey() const;
|
|
||||||
|
|
||||||
// Clears any test data inside this root of trust.
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
// DRM Certificate-based root of trust API.
|
|
||||||
|
|
||||||
// Returns the shared RSA private key from the built-in DRM
|
|
||||||
// Certificate.
|
|
||||||
RSA_shared_ptr& SharedRsaKey() {
|
|
||||||
return test_rsa_key_.get() != nullptr ? test_rsa_key_ : rsa_key_;
|
|
||||||
}
|
|
||||||
RSA* rsa_key() {
|
|
||||||
return test_rsa_key_.get() != nullptr ? test_rsa_key_.get()
|
|
||||||
: rsa_key_.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loads the system's built-in RSA key. Only implemented for
|
const std::vector<uint8_t>& DeviceKey(bool use_real_keybox = false) {
|
||||||
// devices that are that pre-provisioned with a built-in DRM
|
return use_real_keybox ? real_keybox().device_key() :
|
||||||
// Certificate,
|
keybox().device_key();
|
||||||
// This method implements the expected behavior of
|
|
||||||
// OEMCrypto_LoadTestRSAKey().
|
|
||||||
OEMCryptoResult LoadTestRsaKey();
|
|
||||||
|
|
||||||
// Removes any installed test RSA key.
|
|
||||||
void RemoveTestRsaKey() { test_rsa_key_.reset(); }
|
|
||||||
|
|
||||||
// Keybox-based root of trust API.
|
|
||||||
|
|
||||||
// Returns the currently installed keybox (or test keybox) if any
|
|
||||||
// present. The test keybox takes priority over the standard.
|
|
||||||
WvKeybox* keybox() const {
|
|
||||||
return test_keybox_ ? test_keybox_.get() : keybox_.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks the validity of the keybox regardless of the provisioning
|
const std::vector<uint8_t>& DeviceId() {
|
||||||
// method.
|
return keybox().device_id();
|
||||||
OEMCryptoResult IsKeyboxValid() const;
|
}
|
||||||
|
|
||||||
// Installs a clear WV keybox as the root of trust.
|
size_t DeviceTokenLength() {
|
||||||
// A keybox can only be installed once, however, the provisioning
|
return keybox().key_data_length();
|
||||||
// method stated at initialization remains the same.
|
}
|
||||||
//
|
|
||||||
// This method is similar to the expected behavior of
|
|
||||||
// OEMCrypto_InstallKeyboxOrOEMCert() for keybox devices except
|
|
||||||
// that the keybox provided here must be decrypted before installing.
|
|
||||||
OEMCryptoResult InstallKeybox(const uint8_t* keybox_data,
|
|
||||||
size_t keybox_length);
|
|
||||||
|
|
||||||
// Installs a clear test WV keybox. Only settable for devices that
|
const uint8_t* DeviceToken() {
|
||||||
// uses a keybox for provisioning.
|
return keybox().key_data();
|
||||||
//
|
}
|
||||||
// This method is similar to the expected behavior of
|
|
||||||
// OEMCrypto_LoadTestKeybox() for keybox devices except that
|
|
||||||
// the keybox provided here must be decrypted before installing.
|
|
||||||
OEMCryptoResult InstallTestKeybox(const uint8_t* keybox_data,
|
|
||||||
size_t keybox_length);
|
|
||||||
|
|
||||||
// Removes any installed test keybox.
|
WvKeybox& keybox() { return use_test_keybox_ ? test_keybox_ : keybox_; }
|
||||||
void RemoveTestKeybox() { test_keybox_.reset(); }
|
bool UseTestKeybox(const uint8_t* keybox_data, size_t keybox_length) {
|
||||||
|
use_test_keybox_ = true;
|
||||||
|
return test_keybox_.InstallKeybox(keybox_data, keybox_length);
|
||||||
|
}
|
||||||
|
|
||||||
// Gets the keybox key data.
|
RSA_shared_ptr& SharedRsaKey() { return rsa_key_; }
|
||||||
// Implements the expected behavior of OEMCrypto_GetKeyData().
|
RSA* rsa_key() { return rsa_key_.get(); }
|
||||||
OEMCryptoResult GetKeyData(uint8_t* key_data, size_t* key_data_length) const;
|
bool LoadTestRsaKey();
|
||||||
|
void Clear() { use_test_keybox_ = false; }
|
||||||
// OEM Certificate-base root of trust API.
|
|
||||||
|
|
||||||
// For OEM Cert-based devices, returns the OEM Public Certificate
|
|
||||||
// component of the OEM Certificate.
|
|
||||||
// This method implements the expected behavior of
|
|
||||||
// OEMCrypto_GetOEMPublicCertificate().
|
|
||||||
OEMCryptoResult GetOemPublicCertificate(uint8_t* public_cert,
|
|
||||||
size_t* public_cert_length) const;
|
|
||||||
|
|
||||||
// Returns the OEM private key. Intended to be used when loading
|
|
||||||
// the OEM private key into a session.
|
|
||||||
// Should only be called for devices that use OEM Certificates
|
|
||||||
// for provisioning.
|
|
||||||
const std::vector<uint8_t>& GetOemPrivateKey() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEMCrypto_ProvisioningMethod prov_method_ = OEMCrypto_ProvisioningError;
|
OEMCrypto_ProvisioningMethod provisioning_method_;
|
||||||
|
WvKeybox& real_keybox() { return keybox_; }
|
||||||
|
|
||||||
|
WvKeybox keybox_;
|
||||||
|
WvKeybox test_keybox_;
|
||||||
|
bool use_test_keybox_;
|
||||||
|
|
||||||
// DRM certificate.
|
|
||||||
// TODO(b/168544740): Remove |rsa_key_set_| when RSA_shared_ptr has
|
|
||||||
// been replaced with scoped RsaPrivateKey.
|
|
||||||
bool rsa_key_set_ = false;
|
|
||||||
RSA_shared_ptr rsa_key_; // If no keybox, this is baked in certificate.
|
RSA_shared_ptr rsa_key_; // If no keybox, this is baked in certificate.
|
||||||
RSA_shared_ptr test_rsa_key_;
|
|
||||||
|
|
||||||
// Keybox data.
|
|
||||||
std::unique_ptr<WvKeybox> keybox_;
|
|
||||||
std::unique_ptr<WvKeybox> test_keybox_;
|
|
||||||
|
|
||||||
CORE_DISALLOW_COPY_AND_ASSIGN(AuthenticationRoot);
|
CORE_DISALLOW_COPY_AND_ASSIGN(AuthenticationRoot);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wvoec_ref
|
} // namespace wvoec_ref
|
||||||
|
|
||||||
#endif // OEMCRYPTO_AUTH_REF_H_
|
#endif // OEMCRYPTO_AUTH_REF_H_
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ namespace wvoec_ref {
|
|||||||
// for methods that are configured for specific configurations.
|
// for methods that are configured for specific configurations.
|
||||||
|
|
||||||
CryptoEngine::CryptoEngine(std::unique_ptr<wvcdm::FileSystem>&& file_system)
|
CryptoEngine::CryptoEngine(std::unique_ptr<wvcdm::FileSystem>&& file_system)
|
||||||
: file_system_(std::move(file_system)), usage_table_() {
|
: root_of_trust_(config_provisioning_method()),
|
||||||
|
file_system_(std::move(file_system)),
|
||||||
|
usage_table_() {
|
||||||
ERR_load_crypto_strings();
|
ERR_load_crypto_strings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ bool CryptoEngine::Initialize() {
|
|||||||
std::string file_path = GetUsageTimeFileFullPath();
|
std::string file_path = GetUsageTimeFileFullPath();
|
||||||
LoadOfflineTimeInfo(file_path);
|
LoadOfflineTimeInfo(file_path);
|
||||||
usage_table_.reset(MakeUsageTable());
|
usage_table_.reset(MakeUsageTable());
|
||||||
return root_of_trust_.Initialize(config_provisioning_method());
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CryptoEngine::Terminate() {
|
void CryptoEngine::Terminate() {
|
||||||
|
|||||||
@@ -65,40 +65,31 @@ class CryptoEngine {
|
|||||||
|
|
||||||
virtual bool Initialize();
|
virtual bool Initialize();
|
||||||
|
|
||||||
bool ValidRootOfTrust() const { return root_of_trust_.IsValid(); }
|
bool ValidRootOfTrust() { return root_of_trust_.Validate(); }
|
||||||
|
|
||||||
OEMCryptoResult InstallKeybox(const uint8_t* keybox, size_t keybox_length) {
|
bool InstallKeybox(const uint8_t* keybox, size_t keybox_length) {
|
||||||
return root_of_trust_.InstallKeybox(keybox, keybox_length);
|
return root_of_trust_.InstallKeybox(keybox, keybox_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult InstallTestKeybox(const uint8_t* keybox_data,
|
bool UseTestKeybox(const uint8_t* keybox_data, size_t keybox_length) {
|
||||||
size_t keybox_length) {
|
return root_of_trust_.UseTestKeybox(keybox_data, keybox_length);
|
||||||
return root_of_trust_.InstallTestKeybox(keybox_data, keybox_length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult LoadTestRsaKey() { return root_of_trust_.LoadTestRsaKey(); }
|
bool LoadTestRsaKey() { return root_of_trust_.LoadTestRsaKey(); }
|
||||||
|
|
||||||
OEMCryptoResult IsKeyboxValid() const {
|
KeyboxError ValidateKeybox() { return root_of_trust_.ValidateKeybox(); }
|
||||||
return root_of_trust_.IsKeyboxValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> DeviceRootKey() const {
|
const std::vector<uint8_t>& DeviceRootKey() {
|
||||||
return root_of_trust_.DeviceKey();
|
return root_of_trust_.DeviceKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult GetDeviceRootId(uint8_t* device_id,
|
const std::vector<uint8_t>& DeviceRootId() {
|
||||||
size_t* device_id_length) const {
|
|
||||||
return root_of_trust_.GetDeviceId(device_id, device_id_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> DeviceRootId() const {
|
|
||||||
return root_of_trust_.DeviceId();
|
return root_of_trust_.DeviceId();
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult GetRootKeyData(uint8_t* key_data,
|
size_t DeviceRootTokenLength() { return root_of_trust_.DeviceTokenLength(); }
|
||||||
size_t* key_data_length) const {
|
|
||||||
return root_of_trust_.GetKeyData(key_data, key_data_length);
|
const uint8_t* DeviceRootToken() { return root_of_trust_.DeviceToken(); }
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Terminate();
|
virtual void Terminate();
|
||||||
|
|
||||||
|
|||||||
@@ -17,113 +17,58 @@
|
|||||||
#include "wvcrc32.h"
|
#include "wvcrc32.h"
|
||||||
|
|
||||||
namespace wvoec_ref {
|
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,
|
WvKeybox::WvKeybox() : loaded_(false) {
|
||||||
"Unexpected keybox size");
|
static std::string fake_device_id = "device_with_no_keybox";
|
||||||
|
device_id_.assign(fake_device_id.begin(), fake_device_id.end());
|
||||||
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
|
KeyboxError WvKeybox::Validate() {
|
||||||
std::unique_ptr<WvKeybox> WvKeybox::Create(const uint8_t* keybox_data,
|
if (!loaded_) {
|
||||||
size_t keybox_length) {
|
LOGE("[KEYBOX NOT LOADED]");
|
||||||
std::unique_ptr<WvKeybox> keybox;
|
return OTHER_ERROR;
|
||||||
if (keybox_length != kKeyboxSize) {
|
|
||||||
LOGE("Invalid keybox length: length = %zu", keybox_length);
|
|
||||||
return keybox;
|
|
||||||
}
|
}
|
||||||
keybox.reset(new WvKeybox());
|
if (strncmp(reinterpret_cast<char*>(magic_), "kbox", 4) != 0) {
|
||||||
memcpy(reinterpret_cast<uint8_t*>(&keybox->raw_keybox_), keybox_data,
|
LOGE("[KEYBOX HAS BAD MAGIC]");
|
||||||
kKeyboxSize);
|
return BAD_MAGIC;
|
||||||
return keybox;
|
}
|
||||||
|
uint32_t crc_computed;
|
||||||
|
uint32_t crc_stored;
|
||||||
|
uint8_t* crc_stored_bytes = (uint8_t*)&crc_stored;
|
||||||
|
memcpy(crc_stored_bytes, crc_, sizeof(crc_));
|
||||||
|
wvoec::WidevineKeybox keybox;
|
||||||
|
memset(&keybox, 0, sizeof(keybox));
|
||||||
|
memcpy(keybox.device_id_, &device_id_[0], device_id_.size());
|
||||||
|
memcpy(keybox.device_key_, &device_key_[0], sizeof(keybox.device_key_));
|
||||||
|
memcpy(keybox.data_, key_data_, sizeof(keybox.data_));
|
||||||
|
memcpy(keybox.magic_, magic_, sizeof(keybox.magic_));
|
||||||
|
|
||||||
|
crc_computed = ntohl(wvcrc32(reinterpret_cast<uint8_t*>(&keybox),
|
||||||
|
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);
|
||||||
|
return BAD_CRC;
|
||||||
|
}
|
||||||
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult WvKeybox::GetDeviceId(uint8_t* device_id,
|
bool WvKeybox::InstallKeybox(const uint8_t* buffer, size_t keyBoxLength) {
|
||||||
size_t* device_id_length) const {
|
if (keyBoxLength != 128) {
|
||||||
if (device_id_length == nullptr) {
|
return false;
|
||||||
LOGE("Output device ID length buffer is null");
|
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
||||||
}
|
}
|
||||||
if (device_id == nullptr && *device_id_length > 0) {
|
const wvoec::WidevineKeybox* keybox =
|
||||||
LOGE("Output device ID buffer is null");
|
reinterpret_cast<const wvoec::WidevineKeybox*>(buffer);
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
size_t device_id_length =
|
||||||
}
|
strnlen(reinterpret_cast<const char*>(keybox->device_id_), 32);
|
||||||
if (*device_id_length < kDeviceIdSize) {
|
device_id_.assign(keybox->device_id_, keybox->device_id_ + device_id_length);
|
||||||
*device_id_length = kDeviceIdSize;
|
device_key_.assign(keybox->device_key_,
|
||||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
keybox->device_key_ + sizeof(keybox->device_key_));
|
||||||
}
|
memcpy(key_data_, keybox->data_, sizeof(keybox->data_));
|
||||||
*device_id_length = kDeviceIdSize;
|
memcpy(magic_, keybox->magic_, sizeof(keybox->magic_));
|
||||||
memcpy(device_id, raw_keybox_.device_id_, kDeviceIdSize);
|
memcpy(crc_, keybox->crc_, sizeof(keybox->crc_));
|
||||||
return OEMCrypto_SUCCESS;
|
loaded_ = true;
|
||||||
}
|
return true;
|
||||||
|
|
||||||
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
|
} // namespace wvoec_ref
|
||||||
|
|||||||
@@ -7,58 +7,38 @@
|
|||||||
#ifndef OEMCRYPTO_KEYBOX_REF_H_
|
#ifndef OEMCRYPTO_KEYBOX_REF_H_
|
||||||
#define OEMCRYPTO_KEYBOX_REF_H_
|
#define OEMCRYPTO_KEYBOX_REF_H_
|
||||||
|
|
||||||
#include <memory>
|
#include "oemcrypto_key_ref.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "OEMCryptoCENCCommon.h"
|
|
||||||
#include "oemcrypto_types.h"
|
|
||||||
|
|
||||||
namespace wvoec_ref {
|
namespace wvoec_ref {
|
||||||
|
|
||||||
|
const int DEVICE_KEY_LENGTH = 16;
|
||||||
|
typedef uint8_t WvKeyboxKey[DEVICE_KEY_LENGTH];
|
||||||
|
|
||||||
|
const int KEY_DATA_LENGTH = 72;
|
||||||
|
typedef uint8_t WvKeyboxKeyData[KEY_DATA_LENGTH];
|
||||||
|
|
||||||
|
enum KeyboxError { NO_ERROR, BAD_CRC, BAD_MAGIC, OTHER_ERROR };
|
||||||
|
|
||||||
// Widevine keybox
|
// Widevine keybox
|
||||||
class WvKeybox {
|
class WvKeybox {
|
||||||
public:
|
public:
|
||||||
// Validates keybox data using the following rules:
|
WvKeybox();
|
||||||
// 1. Data is not null
|
|
||||||
// 2. Keybox size
|
|
||||||
// 3. Matching magic
|
|
||||||
// 4. CRC-32 check
|
|
||||||
static OEMCryptoResult ValidateData(const uint8_t* keybox_data,
|
|
||||||
size_t keybox_length);
|
|
||||||
|
|
||||||
// Creates a keybox from the provided keybox data.
|
|
||||||
// Provided keybox data must be the proper length, but does
|
|
||||||
// not need to be valid.
|
|
||||||
// Once created, keyboxes are immutable.
|
|
||||||
static std::unique_ptr<WvKeybox> Create(const uint8_t* keybox_data,
|
|
||||||
size_t keybox_length);
|
|
||||||
|
|
||||||
// Gets the device ID from the keybox.
|
|
||||||
// Similar to the expected behavior of OEMCrypto_GetDeviceID().
|
|
||||||
OEMCryptoResult GetDeviceId(uint8_t* device_id,
|
|
||||||
size_t* device_id_length) const;
|
|
||||||
// Returns the keybox device ID directly. Intended to be used
|
|
||||||
// for core message generation.
|
|
||||||
std::vector<uint8_t> DeviceId() const;
|
|
||||||
|
|
||||||
// Returns the keybox device key directly. Intended to be used
|
|
||||||
// for key derivation.
|
|
||||||
std::vector<uint8_t> DeviceKey() const;
|
|
||||||
|
|
||||||
// Gets the keybox data.
|
|
||||||
// Similar to the expected behavior of OEMCrypto_GetKeyData().
|
|
||||||
OEMCryptoResult GetKeyData(uint8_t* key_data, size_t* key_data_length) const;
|
|
||||||
|
|
||||||
// Checks the current keybox instantiation that it is valid.
|
|
||||||
// Similar to the expected behavior of OEMCrypto_IsKeyboxValid().
|
|
||||||
OEMCryptoResult IsKeyboxValid() const;
|
|
||||||
|
|
||||||
~WvKeybox() {}
|
~WvKeybox() {}
|
||||||
|
|
||||||
private:
|
KeyboxError Validate();
|
||||||
WvKeybox() {}
|
const std::vector<uint8_t>& device_id() { return device_id_; }
|
||||||
|
std::vector<uint8_t>& device_key() { return device_key_; }
|
||||||
|
const WvKeyboxKeyData& key_data() { return key_data_; }
|
||||||
|
size_t key_data_length() { return KEY_DATA_LENGTH; }
|
||||||
|
bool InstallKeybox(const uint8_t* keybox, size_t keyBoxLength);
|
||||||
|
|
||||||
wvoec::WidevineKeybox raw_keybox_;
|
private:
|
||||||
|
bool loaded_;
|
||||||
|
std::vector<uint8_t> device_id_;
|
||||||
|
std::vector<uint8_t> device_key_;
|
||||||
|
WvKeyboxKeyData key_data_;
|
||||||
|
uint8_t magic_[4];
|
||||||
|
uint8_t crc_[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wvoec_ref
|
} // namespace wvoec_ref
|
||||||
|
|||||||
@@ -733,7 +733,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_WrapKeyboxOrOEMCert(
|
|||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult
|
OEMCRYPTO_API OEMCryptoResult
|
||||||
OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* keybox, size_t keybox_length) {
|
OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* keybox, size_t keyBoxLength) {
|
||||||
if (crypto_engine == nullptr) {
|
if (crypto_engine == nullptr) {
|
||||||
LOGE("OEMCrypto_InstallKeyboxOrOEMCert: OEMCrypto Not Initialized.");
|
LOGE("OEMCrypto_InstallKeyboxOrOEMCert: OEMCrypto Not Initialized.");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
@@ -741,7 +741,10 @@ OEMCrypto_InstallKeyboxOrOEMCert(const uint8_t* keybox, size_t keybox_length) {
|
|||||||
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
|
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
return crypto_engine->InstallKeybox(keybox, keybox_length);
|
if (crypto_engine->InstallKeybox(keybox, keyBoxLength)) {
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
|
}
|
||||||
|
return OEMCrypto_ERROR_WRITE_KEYBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
|
||||||
@@ -753,7 +756,10 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadTestKeybox(const uint8_t* buffer,
|
|||||||
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
|
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
return crypto_engine->InstallTestKeybox(buffer, length);
|
if (crypto_engine->UseTestKeybox(buffer, length)) {
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
|
}
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) {
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) {
|
||||||
@@ -765,10 +771,22 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_IsKeyboxOrOEMCertValid(void) {
|
|||||||
case OEMCrypto_DrmCertificate:
|
case OEMCrypto_DrmCertificate:
|
||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
case OEMCrypto_Keybox:
|
case OEMCrypto_Keybox:
|
||||||
return crypto_engine->IsKeyboxValid();
|
switch (crypto_engine->ValidateKeybox()) {
|
||||||
|
case NO_ERROR:
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
|
case BAD_CRC:
|
||||||
|
return OEMCrypto_ERROR_BAD_CRC;
|
||||||
|
case BAD_MAGIC:
|
||||||
|
return OEMCrypto_ERROR_BAD_MAGIC;
|
||||||
|
default:
|
||||||
|
case OTHER_ERROR:
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case OEMCrypto_OEMCertificate:
|
case OEMCrypto_OEMCertificate:
|
||||||
// TODO(sigquit): verify that the certificate exists and is valid.
|
// TODO(fredgc): verify that the certificate exists and is valid.
|
||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOGE("Invalid provisioning method: %d.",
|
LOGE("Invalid provisioning method: %d.",
|
||||||
crypto_engine->config_provisioning_method());
|
crypto_engine->config_provisioning_method());
|
||||||
@@ -817,17 +835,32 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetOEMPublicCertificate(
|
|||||||
return crypto_engine->get_oem_certificate(public_cert, public_cert_length);
|
return crypto_engine->get_oem_certificate(public_cert, public_cert_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* device_id,
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
|
||||||
size_t* device_id_length) {
|
size_t* idLength) {
|
||||||
if (crypto_engine == nullptr) {
|
if (crypto_engine == nullptr) {
|
||||||
LOGE("OEMCrypto_GetDeviceID: OEMCrypto Not Initialized.");
|
LOGE("OEMCrypto_GetDeviceID: OEMCrypto Not Initialized.");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
return crypto_engine->GetDeviceRootId(device_id, device_id_length);
|
const std::vector<uint8_t>& dev_id_string = crypto_engine->DeviceRootId();
|
||||||
|
if (dev_id_string.empty()) {
|
||||||
|
LOGE("[OEMCrypto_GetDeviceId(): Keybox Invalid]");
|
||||||
|
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t dev_id_len = dev_id_string.size();
|
||||||
|
if (*idLength < dev_id_len) {
|
||||||
|
*idLength = dev_id_len;
|
||||||
|
LOGE("[OEMCrypto_GetDeviceId(): ERROR_SHORT_BUFFER]");
|
||||||
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
|
}
|
||||||
|
memset(deviceID, 0, *idLength);
|
||||||
|
memcpy(deviceID, &dev_id_string[0], dev_id_len);
|
||||||
|
*idLength = dev_id_len;
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* key_data,
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
|
||||||
size_t* key_data_length) {
|
size_t* keyDataLength) {
|
||||||
if (crypto_engine == nullptr) {
|
if (crypto_engine == nullptr) {
|
||||||
LOGE("OEMCrypto_GetKeyData: OEMCrypto Not Initialized.");
|
LOGE("OEMCrypto_GetKeyData: OEMCrypto Not Initialized.");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
@@ -835,7 +868,24 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* key_data,
|
|||||||
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
|
if (crypto_engine->config_provisioning_method() != OEMCrypto_Keybox) {
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
return crypto_engine->GetRootKeyData(key_data, key_data_length);
|
size_t length = crypto_engine->DeviceRootTokenLength();
|
||||||
|
if (keyDataLength == nullptr) {
|
||||||
|
LOGE("[OEMCrypto_GetKeyData(): null pointer. ERROR_UNKNOWN_FAILURE]");
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
if (*keyDataLength < length) {
|
||||||
|
*keyDataLength = length;
|
||||||
|
LOGE("[OEMCrypto_GetKeyData(): ERROR_SHORT_BUFFER]");
|
||||||
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
|
}
|
||||||
|
if (keyData == nullptr) {
|
||||||
|
LOGE("[OEMCrypto_GetKeyData(): null pointer. ERROR_UNKNOWN_FAILURE]");
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
memset(keyData, 0, *keyDataLength);
|
||||||
|
memcpy(keyData, crypto_engine->DeviceRootToken(), length);
|
||||||
|
*keyDataLength = length;
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
|
||||||
@@ -1209,7 +1259,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadTestRSAKey() {
|
|||||||
LOGE("OEMCrypto_LoadTestRSAKey: OEMCrypto Not Initialized.");
|
LOGE("OEMCrypto_LoadTestRSAKey: OEMCrypto Not Initialized.");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
return crypto_engine->LoadTestRsaKey();
|
if (crypto_engine->LoadTestRsaKey()) return OEMCrypto_SUCCESS;
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ OEMCryptoResult SessionContext::PrepAndSignProvisioningRequest(
|
|||||||
}
|
}
|
||||||
const size_t required_signature_size = ROTSignatureSize();
|
const size_t required_signature_size = ROTSignatureSize();
|
||||||
if (required_signature_size == 0) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
if (required_signature_size == 0) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
const std::vector<uint8_t> device_id = ce_->DeviceRootId();
|
const std::vector<uint8_t>& device_id = ce_->DeviceRootId();
|
||||||
OEMCryptoResult result = ODK_PrepareCoreProvisioningRequest(
|
OEMCryptoResult result = ODK_PrepareCoreProvisioningRequest(
|
||||||
message, message_length, core_message_length, &nonce_values_,
|
message, message_length, core_message_length, &nonce_values_,
|
||||||
device_id.data(), device_id.size());
|
device_id.data(), device_id.size());
|
||||||
|
|||||||
Reference in New Issue
Block a user