[DO NOT MERGE] Revert "Restructed reference root of trust (2/3 DRM Cert)"
This reverts commit f6f5099604.
Reason for revert: Feature missed deadline
Bug: 135283522
Change-Id: Ic86930ee3444c5a6aa1d78ae3a12a9030c29ef92
This commit is contained in:
@@ -187,6 +187,7 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) {
|
|||||||
// If provisioning method is something other than ProvisioningError
|
// If provisioning method is something other than ProvisioningError
|
||||||
// indicates it has already been initialized before. Must
|
// indicates it has already been initialized before. Must
|
||||||
// existing data.
|
// existing data.
|
||||||
|
rsa_key_set_ = false;
|
||||||
rsa_key_.reset();
|
rsa_key_.reset();
|
||||||
test_rsa_key_.reset();
|
test_rsa_key_.reset();
|
||||||
keybox_.reset();
|
keybox_.reset();
|
||||||
@@ -195,11 +196,8 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) {
|
|||||||
prov_method_ = method;
|
prov_method_ = method;
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case OEMCrypto_DrmCertificate: {
|
case OEMCrypto_DrmCertificate: {
|
||||||
std::unique_ptr<RsaPrivateKey> key =
|
rsa_key_set_ = rsa_key_.LoadPkcs8RsaKey(kPrivateKey, kPrivateKeySize);
|
||||||
RsaPrivateKey::Load(kPrivateKey, kPrivateKeySize);
|
if (!rsa_key_set_) {
|
||||||
if (key) {
|
|
||||||
rsa_key_ = std::move(key);
|
|
||||||
} else {
|
|
||||||
// This error message is OK in unit tests which use test certificate.
|
// This error message is OK in unit tests which use test certificate.
|
||||||
LOGE(
|
LOGE(
|
||||||
"FATAL ERROR: Platform uses a baked-in certificate instead of a "
|
"FATAL ERROR: Platform uses a baked-in certificate instead of a "
|
||||||
@@ -224,7 +222,7 @@ bool AuthenticationRoot::Initialize(OEMCrypto_ProvisioningMethod method) {
|
|||||||
bool AuthenticationRoot::IsValid() const {
|
bool AuthenticationRoot::IsValid() const {
|
||||||
switch (prov_method_) {
|
switch (prov_method_) {
|
||||||
case OEMCrypto_DrmCertificate: {
|
case OEMCrypto_DrmCertificate: {
|
||||||
return HasDrmCertKey() && HasDeviceKey();
|
return rsa_key_set_ && HasDeviceKey();
|
||||||
}
|
}
|
||||||
case OEMCrypto_Keybox: {
|
case OEMCrypto_Keybox: {
|
||||||
return HasDeviceKey();
|
return HasDeviceKey();
|
||||||
@@ -326,18 +324,17 @@ OEMCryptoResult AuthenticationRoot::LoadTestRsaKey() {
|
|||||||
LOGE("System does not support DRM certificates");
|
LOGE("System does not support DRM certificates");
|
||||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
if (test_rsa_key_) {
|
if (test_rsa_key_.get() != nullptr) {
|
||||||
LOGE("Test RSA key is already loaded");
|
LOGE("Test RSA key is already loaded");
|
||||||
return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES;
|
return OEMCrypto_ERROR_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
std::unique_ptr<RsaPrivateKey> key =
|
if (!test_rsa_key_.LoadPkcs8RsaKey(
|
||||||
RsaPrivateKey::Load(kTestRSAPKCS8PrivateKeyInfo2_2048,
|
kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048))) {
|
||||||
if (!key) {
|
|
||||||
LOGE("Failed to load test RSA key");
|
LOGE("Failed to load test RSA key");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
test_rsa_key_ = std::move(key);
|
rsa_key_set_ = true;
|
||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,17 @@
|
|||||||
#define OEMCRYPTO_AUTH_REF_H_
|
#define OEMCRYPTO_AUTH_REF_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
#include "OEMCryptoCENC.h" // Needed for enums only.
|
#include "OEMCryptoCENC.h" // Needed for enums only.
|
||||||
#include "disallow_copy_and_assign.h"
|
#include "disallow_copy_and_assign.h"
|
||||||
|
#include "oemcrypto_key_ref.h"
|
||||||
#include "oemcrypto_keybox_ref.h"
|
#include "oemcrypto_keybox_ref.h"
|
||||||
#include "oemcrypto_rsa_key.h"
|
#include "oemcrypto_rsa_key_shared.h"
|
||||||
|
#include "oemcrypto_types.h"
|
||||||
|
|
||||||
namespace wvoec_ref {
|
namespace wvoec_ref {
|
||||||
// The AuthenticationRoot class contains the OEMCrypto information
|
// The AuthenticationRoot class contains the OEMCrypto information
|
||||||
@@ -66,13 +69,13 @@ class AuthenticationRoot {
|
|||||||
|
|
||||||
// Returns the shared RSA private key from the built-in DRM
|
// Returns the shared RSA private key from the built-in DRM
|
||||||
// Certificate.
|
// Certificate.
|
||||||
std::shared_ptr<RsaPrivateKey> ShareDrmCertKey() {
|
RSA_shared_ptr& SharedRsaKey() {
|
||||||
return test_rsa_key_ ? test_rsa_key_ : rsa_key_;
|
return test_rsa_key_.get() != nullptr ? test_rsa_key_ : rsa_key_;
|
||||||
}
|
}
|
||||||
RsaPrivateKey* DrmCertKey() const {
|
RSA* rsa_key() {
|
||||||
return test_rsa_key_ ? test_rsa_key_.get() : rsa_key_.get();
|
return test_rsa_key_.get() != nullptr ? test_rsa_key_.get()
|
||||||
|
: rsa_key_.get();
|
||||||
}
|
}
|
||||||
bool HasDrmCertKey() const { return test_rsa_key_ || rsa_key_; }
|
|
||||||
|
|
||||||
// Loads the system's built-in RSA key. Only implemented for
|
// Loads the system's built-in RSA key. Only implemented for
|
||||||
// devices that are that pre-provisioned with a built-in DRM
|
// devices that are that pre-provisioned with a built-in DRM
|
||||||
@@ -141,10 +144,11 @@ class AuthenticationRoot {
|
|||||||
OEMCrypto_ProvisioningMethod prov_method_ = OEMCrypto_ProvisioningError;
|
OEMCrypto_ProvisioningMethod prov_method_ = OEMCrypto_ProvisioningError;
|
||||||
|
|
||||||
// DRM certificate.
|
// DRM certificate.
|
||||||
// If no keybox, this is the private key of the baked-in DRM
|
// TODO(b/168544740): Remove |rsa_key_set_| when RSA_shared_ptr has
|
||||||
// Certificate.
|
// been replaced with scoped RsaPrivateKey.
|
||||||
std::shared_ptr<RsaPrivateKey> rsa_key_;
|
bool rsa_key_set_ = false;
|
||||||
std::shared_ptr<RsaPrivateKey> test_rsa_key_;
|
RSA_shared_ptr rsa_key_; // If no keybox, this is baked in certificate.
|
||||||
|
RSA_shared_ptr test_rsa_key_;
|
||||||
|
|
||||||
// Keybox data.
|
// Keybox data.
|
||||||
std::unique_ptr<WvKeybox> keybox_;
|
std::unique_ptr<WvKeybox> keybox_;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class Prov30CryptoEngine : public CryptoEngine {
|
|||||||
return OEMCrypto_ERROR_SHORT_BUFFER;
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
}
|
}
|
||||||
memcpy(public_cert, kOEMPublicCert, kOEMPublicCertSize);
|
memcpy(public_cert, kOEMPublicCert, kOEMPublicCertSize);
|
||||||
if (!session->LoadRsaDrmKey(kOEMPrivateKey, kOEMPrivateKeySize)) {
|
if (!session->LoadRSAKey(kOEMPrivateKey, kOEMPrivateKeySize)) {
|
||||||
LOGE("Private RSA Key did not load correctly.");
|
LOGE("Private RSA Key did not load correctly.");
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "oemcrypto_key_ref.h"
|
#include "oemcrypto_key_ref.h"
|
||||||
|
#include "oemcrypto_rsa_key_shared.h"
|
||||||
#include "string_conversions.h"
|
#include "string_conversions.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -80,10 +81,7 @@ SessionId CryptoEngine::OpenSession() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SessionContext* CryptoEngine::MakeSession(SessionId sid) {
|
SessionContext* CryptoEngine::MakeSession(SessionId sid) {
|
||||||
if (root_of_trust_.HasDrmCertKey()) {
|
return new SessionContext(this, sid, root_of_trust_.SharedRsaKey());
|
||||||
return new SessionContext(this, sid, root_of_trust_.ShareDrmCertKey());
|
|
||||||
}
|
|
||||||
return new SessionContext(this, sid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UsageTable* CryptoEngine::MakeUsageTable() { return new UsageTable(this); }
|
UsageTable* CryptoEngine::MakeUsageTable() { return new UsageTable(this); }
|
||||||
|
|||||||
@@ -8,16 +8,19 @@
|
|||||||
#define REF_OEMCRYPTO_ENGINE_REF_H_
|
#define REF_OEMCRYPTO_ENGINE_REF_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
#include "OEMCryptoCENC.h"
|
#include "OEMCryptoCENC.h"
|
||||||
#include "file_store.h"
|
#include "file_store.h"
|
||||||
#include "oemcrypto_auth_ref.h"
|
#include "oemcrypto_auth_ref.h"
|
||||||
#include "oemcrypto_key_ref.h"
|
#include "oemcrypto_key_ref.h"
|
||||||
|
#include "oemcrypto_rsa_key_shared.h"
|
||||||
#include "oemcrypto_session.h"
|
#include "oemcrypto_session.h"
|
||||||
#include "oemcrypto_types.h"
|
#include "oemcrypto_types.h"
|
||||||
#include "oemcrypto_usage_table_ref.h"
|
#include "oemcrypto_usage_table_ref.h"
|
||||||
|
|||||||
@@ -172,8 +172,11 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
|
|||||||
enc_key_context, enc_key_context + enc_key_context_length);
|
enc_key_context, enc_key_context + enc_key_context_length);
|
||||||
|
|
||||||
// Generate mac and encryption keys for current session context
|
// Generate mac and encryption keys for current session context
|
||||||
return session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str,
|
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), mac_ctx_str,
|
||||||
enc_ctx_str);
|
enc_ctx_str)) {
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
|
||||||
@@ -890,10 +893,8 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
|||||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<uint8_t> enc_encryption_key(
|
if (!session_ctx->InstallRSAEncryptedKey(encrypted_message_key,
|
||||||
encrypted_message_key,
|
encrypted_message_key_length)) {
|
||||||
encrypted_message_key + encrypted_message_key_length);
|
|
||||||
if (!session_ctx->InstallRSAEncryptedKey(enc_encryption_key)) {
|
|
||||||
LOGE(
|
LOGE(
|
||||||
"OEMCrypto_RewrapDeviceRSAKey30: "
|
"OEMCrypto_RewrapDeviceRSAKey30: "
|
||||||
"Error loading encrypted_message_key.");
|
"Error loading encrypted_message_key.");
|
||||||
@@ -903,11 +904,11 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
|||||||
// Decrypt RSA key.
|
// Decrypt RSA key.
|
||||||
std::vector<uint8_t> pkcs8_rsa_key(enc_rsa_key_length);
|
std::vector<uint8_t> pkcs8_rsa_key(enc_rsa_key_length);
|
||||||
if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length,
|
if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length,
|
||||||
enc_rsa_key_iv, pkcs8_rsa_key.data())) {
|
enc_rsa_key_iv, &pkcs8_rsa_key[0])) {
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) {
|
if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) {
|
||||||
LOGE("Failed to load RSA DRM key");
|
LOGE("[OEMCrypto_RewrapDeviceRSAKey30(): Failed to LoadRSAKey.");
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -925,24 +926,23 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey30(
|
|||||||
const std::vector<uint8_t> context(
|
const std::vector<uint8_t> context(
|
||||||
wrapped->context, wrapped->context + sizeof(wrapped->context));
|
wrapped->context, wrapped->context + sizeof(wrapped->context));
|
||||||
// Generate mac and encryption keys for encrypting the signature.
|
// Generate mac and encryption keys for encrypting the signature.
|
||||||
const OEMCryptoResult derive_key_result =
|
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context,
|
||||||
session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context);
|
context)) {
|
||||||
if (derive_key_result != OEMCrypto_SUCCESS) {
|
|
||||||
LOGE("[_RewrapDeviceRSAKey30(): DeriveKeys failed.");
|
LOGE("[_RewrapDeviceRSAKey30(): DeriveKeys failed.");
|
||||||
return derive_key_result;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt rsa key with keybox.
|
// Encrypt rsa key with keybox.
|
||||||
if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length,
|
if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length,
|
||||||
wrapped->iv, wrapped->enc_rsa_key)) {
|
wrapped->iv, wrapped->enc_rsa_key)) {
|
||||||
LOGE("[_RewrapDeviceRSAKey30(): EncrypteRSAKey failed.");
|
LOGE("[_RewrapDeviceRSAKey30(): EncrypteRSAKey failed.");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey);
|
const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey);
|
||||||
// The wrapped keybox must be signed with the same key we verify with.
|
// The wrapped keybox must be signed with the same key we verify with. I'll
|
||||||
// Reference implementation uses the server key.
|
// pick the server key, so I don't have to modify LoadRSAKey.
|
||||||
unsigned int sig_length = sizeof(wrapped->signature);
|
unsigned int sig_length = sizeof(wrapped->signature);
|
||||||
if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(),
|
if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0],
|
||||||
session_ctx->mac_key_server().size(), wrapped->context,
|
session_ctx->mac_key_server().size(), wrapped->context,
|
||||||
buffer_size - sizeof(wrapped->signature), wrapped->signature,
|
buffer_size - sizeof(wrapped->signature), wrapped->signature,
|
||||||
&sig_length)) {
|
&sig_length)) {
|
||||||
@@ -1006,10 +1006,10 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
|||||||
// Decrypt RSA key and verify it.
|
// Decrypt RSA key and verify it.
|
||||||
std::vector<uint8_t> pkcs8_rsa_key(enc_rsa_key_length);
|
std::vector<uint8_t> pkcs8_rsa_key(enc_rsa_key_length);
|
||||||
if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length,
|
if (!session_ctx->DecryptRSAKey(enc_rsa_key, enc_rsa_key_length,
|
||||||
enc_rsa_key_iv, pkcs8_rsa_key.data())) {
|
enc_rsa_key_iv, &pkcs8_rsa_key[0])) {
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), enc_rsa_key_length)) {
|
if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length)) {
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1025,22 +1025,21 @@ static OEMCryptoResult OEMCrypto_RewrapDeviceRSAKey(
|
|||||||
const std::vector<uint8_t> context(
|
const std::vector<uint8_t> context(
|
||||||
wrapped->context, wrapped->context + sizeof(wrapped->context));
|
wrapped->context, wrapped->context + sizeof(wrapped->context));
|
||||||
// Generate mac and encryption keys for encrypting the signature.
|
// Generate mac and encryption keys for encrypting the signature.
|
||||||
const OEMCryptoResult derive_key_result =
|
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context,
|
||||||
session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context);
|
context)) {
|
||||||
if (derive_key_result != OEMCrypto_SUCCESS) {
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
return derive_key_result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt rsa key with keybox.
|
// Encrypt rsa key with keybox.
|
||||||
if (!session_ctx->EncryptRSAKey(pkcs8_rsa_key.data(), enc_rsa_key_length,
|
if (!session_ctx->EncryptRSAKey(&pkcs8_rsa_key[0], enc_rsa_key_length,
|
||||||
wrapped->iv, wrapped->enc_rsa_key)) {
|
wrapped->iv, wrapped->enc_rsa_key)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey);
|
const size_t buffer_size = enc_rsa_key_length + sizeof(WrappedRSAKey);
|
||||||
// The wrapped keybox must be signed with the same key we verify with.
|
// The wrapped keybox must be signed with the same key we verify with. I'll
|
||||||
// Reference implementation uses the server key.
|
// pick the server key, so I don't have to modify LoadRSAKey.
|
||||||
unsigned int sig_length = sizeof(wrapped->signature);
|
unsigned int sig_length = sizeof(wrapped->signature);
|
||||||
if (!HMAC(EVP_sha256(), session_ctx->mac_key_server().data(),
|
if (!HMAC(EVP_sha256(), &session_ctx->mac_key_server()[0],
|
||||||
session_ctx->mac_key_server().size(), wrapped->context,
|
session_ctx->mac_key_server().size(), wrapped->context,
|
||||||
buffer_size - sizeof(wrapped->signature), wrapped->signature,
|
buffer_size - sizeof(wrapped->signature), wrapped->signature,
|
||||||
&sig_length)) {
|
&sig_length)) {
|
||||||
@@ -1174,10 +1173,9 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(
|
|||||||
const std::vector<uint8_t> context(
|
const std::vector<uint8_t> context(
|
||||||
wrapped->context, wrapped->context + sizeof(wrapped->context));
|
wrapped->context, wrapped->context + sizeof(wrapped->context));
|
||||||
// Generate mac and encryption keys for encrypting the signature.
|
// Generate mac and encryption keys for encrypting the signature.
|
||||||
const OEMCryptoResult derive_key_result =
|
if (!session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context,
|
||||||
session_ctx->DeriveKeys(crypto_engine->DeviceRootKey(), context, context);
|
context)) {
|
||||||
if (derive_key_result != OEMCrypto_SUCCESS) {
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
return derive_key_result;
|
|
||||||
}
|
}
|
||||||
// verify signature.
|
// verify signature.
|
||||||
if (!session_ctx->ValidateMessage(
|
if (!session_ctx->ValidateMessage(
|
||||||
@@ -1191,7 +1189,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(
|
|||||||
sizeof(wrapped->signature));
|
sizeof(wrapped->signature));
|
||||||
size_t enc_rsa_key_length = wrapped_rsa_key_length - sizeof(WrappedRSAKey);
|
size_t enc_rsa_key_length = wrapped_rsa_key_length - sizeof(WrappedRSAKey);
|
||||||
if (!session_ctx->DecryptRSAKey(wrapped->enc_rsa_key, enc_rsa_key_length,
|
if (!session_ctx->DecryptRSAKey(wrapped->enc_rsa_key, enc_rsa_key_length,
|
||||||
wrapped->iv, pkcs8_rsa_key.data())) {
|
wrapped->iv, &pkcs8_rsa_key[0])) {
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1];
|
size_t padding = pkcs8_rsa_key[enc_rsa_key_length - 1];
|
||||||
@@ -1200,7 +1198,7 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadDRMPrivateKey(
|
|||||||
padding = 0;
|
padding = 0;
|
||||||
}
|
}
|
||||||
size_t rsa_key_length = enc_rsa_key_length - padding;
|
size_t rsa_key_length = enc_rsa_key_length - padding;
|
||||||
if (!session_ctx->LoadRsaDrmKey(pkcs8_rsa_key.data(), rsa_key_length)) {
|
if (!session_ctx->LoadRSAKey(&pkcs8_rsa_key[0], rsa_key_length)) {
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
@@ -1233,8 +1231,22 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateRSASignature(
|
|||||||
LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_INVALID_SESSION]");
|
LOGE("[OEMCrypto_GenerateRSASignature(): ERROR_INVALID_SESSION]");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
return session_ctx->GenerateRSASignature(message, message_length, signature,
|
|
||||||
signature_length, padding_scheme);
|
size_t required_size = session_ctx->RSASignatureSize();
|
||||||
|
if (*signature_length < required_size) {
|
||||||
|
*signature_length = required_size;
|
||||||
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
||||||
|
signature_length == 0) {
|
||||||
|
LOGE("[OEMCrypto_GenerateRSASignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
|
||||||
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult sts = session_ctx->GenerateRSASignature(
|
||||||
|
message, message_length, signature, signature_length, padding_scheme);
|
||||||
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
||||||
@@ -1247,22 +1259,27 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
|||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
if (!crypto_engine->ValidRootOfTrust()) {
|
if (!crypto_engine->ValidRootOfTrust()) {
|
||||||
LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_KEYBOX_INVALID]");
|
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_KEYBOX_INVALID]");
|
||||||
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
return OEMCrypto_ERROR_KEYBOX_INVALID;
|
||||||
}
|
}
|
||||||
if (mac_key_context_length > kMaxContextKeyLength ||
|
if (mac_key_context_length > kMaxContextKeyLength ||
|
||||||
enc_key_context_length > kMaxContextKeyLength ||
|
enc_key_context_length > kMaxContextKeyLength ||
|
||||||
enc_session_key_length > kMaxContextKeyLength) {
|
enc_session_key_length > kMaxContextKeyLength) {
|
||||||
LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_BUFFER_TOO_LARGE]");
|
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_BUFFER_TOO_LARGE]");
|
||||||
return OEMCrypto_ERROR_BUFFER_TOO_LARGE;
|
return OEMCrypto_ERROR_BUFFER_TOO_LARGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
SessionContext* session_ctx = crypto_engine->FindSession(session);
|
||||||
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
if (session_ctx == nullptr || !session_ctx->isValid()) {
|
||||||
LOGE("[OEMCrypto_DeriveKeysFromSessionKey(): ERROR_INVALID_SESSION]");
|
LOGE("[OEMCrypto_GenerateDerivedKeys(): ERROR_INVALID_SESSION]");
|
||||||
return OEMCrypto_ERROR_INVALID_SESSION;
|
return OEMCrypto_ERROR_INVALID_SESSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session_ctx->allowed_schemes() != kSign_RSASSA_PSS) {
|
||||||
|
LOGE("[OEMCrypto_GenerateDerivedKeys(): x509 key used to derive keys]");
|
||||||
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<uint8_t> ssn_key_str(
|
const std::vector<uint8_t> ssn_key_str(
|
||||||
enc_session_key, enc_session_key + enc_session_key_length);
|
enc_session_key, enc_session_key + enc_session_key_length);
|
||||||
const std::vector<uint8_t> mac_ctx_str(
|
const std::vector<uint8_t> mac_ctx_str(
|
||||||
@@ -1271,7 +1288,10 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
|||||||
enc_key_context, enc_key_context + enc_key_context_length);
|
enc_key_context, enc_key_context + enc_key_context_length);
|
||||||
|
|
||||||
// Generate mac and encryption keys for current session context
|
// Generate mac and encryption keys for current session context
|
||||||
return session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str);
|
if (!session_ctx->RSADeriveKeys(ssn_key_str, mac_ctx_str, enc_ctx_str)) {
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCRYPTO_API uint32_t OEMCrypto_APIVersion() {
|
OEMCRYPTO_API uint32_t OEMCrypto_APIVersion() {
|
||||||
|
|||||||
@@ -993,6 +993,7 @@ bool RsaPrivateKey::InitFromBuffer(const uint8_t* buffer, size_t length) {
|
|||||||
}
|
}
|
||||||
// Step 3: Verify field width.
|
// Step 3: Verify field width.
|
||||||
const int bits = RSA_bits(key.get());
|
const int bits = RSA_bits(key.get());
|
||||||
|
LOGD("Loaded RSA private key size: bits = %d", bits);
|
||||||
field_size_ = RealBitSizeToFieldSize(bits);
|
field_size_ = RealBitSizeToFieldSize(bits);
|
||||||
if (field_size_ == kRsaFieldUnknown) {
|
if (field_size_ == kRsaFieldUnknown) {
|
||||||
LOGE("Unsupported RSA key size: bits = %d", bits);
|
LOGE("Unsupported RSA key size: bits = %d", bits);
|
||||||
|
|||||||
101
libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp
Normal file
101
libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.cpp
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||||
|
// source code may only be used and distributed under the Widevine Master
|
||||||
|
// License Agreement.
|
||||||
|
//
|
||||||
|
// Reference implementation of OEMCrypto APIs
|
||||||
|
//
|
||||||
|
#include "oemcrypto_rsa_key_shared.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
namespace wvoec_ref {
|
||||||
|
|
||||||
|
void dump_boringssl_error() {
|
||||||
|
int count = 0;
|
||||||
|
while (unsigned long err = ERR_get_error()) {
|
||||||
|
count++;
|
||||||
|
char buffer[120];
|
||||||
|
ERR_error_string_n(err, buffer, sizeof(buffer));
|
||||||
|
LOGE("BoringSSL Error %d -- %lu -- %s", count, err, buffer);
|
||||||
|
}
|
||||||
|
LOGE("Reported %d BoringSSL Errors", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSA_shared_ptr::reset() {
|
||||||
|
if (rsa_key_ && key_owned_) {
|
||||||
|
RSA_free(rsa_key_);
|
||||||
|
}
|
||||||
|
key_owned_ = false;
|
||||||
|
rsa_key_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RSA_shared_ptr::LoadPkcs8RsaKey(const uint8_t* buffer, size_t length) {
|
||||||
|
assert(buffer != nullptr);
|
||||||
|
reset();
|
||||||
|
uint8_t* pkcs8_rsa_key = const_cast<uint8_t*>(buffer);
|
||||||
|
BIO* bio = BIO_new_mem_buf(pkcs8_rsa_key, length);
|
||||||
|
if (bio == nullptr) {
|
||||||
|
LOGE("[LoadPkcs8RsaKey(): Could not allocate bio buffer]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool success = true;
|
||||||
|
PKCS8_PRIV_KEY_INFO* pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, nullptr);
|
||||||
|
if (pkcs8_pki == nullptr) {
|
||||||
|
BIO_reset(bio);
|
||||||
|
pkcs8_pki = d2i_PKCS8_PRIV_KEY_INFO_bio(bio, nullptr);
|
||||||
|
if (pkcs8_pki == nullptr) {
|
||||||
|
LOGE("[LoadPkcs8RsaKey(): d2i_PKCS8_PRIV_KEY_INFO_bio returned nullptr]");
|
||||||
|
dump_boringssl_error();
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EVP_PKEY* evp = nullptr;
|
||||||
|
if (success) {
|
||||||
|
evp = EVP_PKCS82PKEY(pkcs8_pki);
|
||||||
|
if (evp == nullptr) {
|
||||||
|
LOGE("[LoadPkcs8RsaKey(): EVP_PKCS82PKEY returned nullptr]");
|
||||||
|
dump_boringssl_error();
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (success) {
|
||||||
|
rsa_key_ = EVP_PKEY_get1_RSA(evp);
|
||||||
|
if (rsa_key_ == nullptr) {
|
||||||
|
LOGE("[LoadPkcs8RsaKey(): PrivateKeyInfo did not contain an RSA key]");
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
key_owned_ = true;
|
||||||
|
}
|
||||||
|
if (evp != nullptr) {
|
||||||
|
EVP_PKEY_free(evp);
|
||||||
|
}
|
||||||
|
if (pkcs8_pki != nullptr) {
|
||||||
|
PKCS8_PRIV_KEY_INFO_free(pkcs8_pki);
|
||||||
|
}
|
||||||
|
BIO_free(bio);
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (RSA_check_key(rsa_key_)) {
|
||||||
|
case 1: // valid.
|
||||||
|
return true;
|
||||||
|
case 0: // not valid.
|
||||||
|
LOGE("[LoadPkcs8RsaKey(): rsa key not valid]");
|
||||||
|
dump_boringssl_error();
|
||||||
|
return false;
|
||||||
|
default: // -1 == check failed.
|
||||||
|
LOGE("[LoadPkcs8RsaKey(): error checking rsa key]");
|
||||||
|
dump_boringssl_error();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace wvoec_ref
|
||||||
42
libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h
Normal file
42
libwvdrmengine/oemcrypto/ref/src/oemcrypto_rsa_key_shared.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
||||||
|
// source code may only be used and distributed under the Widevine Master
|
||||||
|
// License Agreement.
|
||||||
|
//
|
||||||
|
// Reference implementation of OEMCrypto APIs
|
||||||
|
//
|
||||||
|
#ifndef OEMCRYPTO_RSA_KEY_SHARED_H_
|
||||||
|
#define OEMCRYPTO_RSA_KEY_SHARED_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
|
namespace wvoec_ref {
|
||||||
|
|
||||||
|
// Shared pointer with specialized destructor. This pointer is only shared
|
||||||
|
// from a CryptoEngine to a Session -- so we don't have to use full reference
|
||||||
|
// counting.
|
||||||
|
class RSA_shared_ptr {
|
||||||
|
public:
|
||||||
|
RSA_shared_ptr() : rsa_key_(nullptr), key_owned_(false) {}
|
||||||
|
~RSA_shared_ptr() { reset(); };
|
||||||
|
// Explicitly allow copy as share.
|
||||||
|
explicit RSA_shared_ptr(const RSA_shared_ptr& other) :
|
||||||
|
rsa_key_(other.rsa_key_), key_owned_(false) {}
|
||||||
|
RSA* get() { return rsa_key_; }
|
||||||
|
void reset();
|
||||||
|
bool LoadPkcs8RsaKey(const uint8_t* buffer, size_t length);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void operator=(const RSA_shared_ptr); // disallow assign.
|
||||||
|
|
||||||
|
RSA* rsa_key_;
|
||||||
|
bool key_owned_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log errors from BoringSSL.
|
||||||
|
void dump_boringssl_error();
|
||||||
|
|
||||||
|
} // namespace wvoec_ref
|
||||||
|
|
||||||
|
#endif // OEMCRYPTO_RSA_KEY_SHARED_H_
|
||||||
@@ -25,17 +25,20 @@
|
|||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
|
||||||
#include "advance_iv_ctr.h"
|
#include "advance_iv_ctr.h"
|
||||||
|
#include "disallow_copy_and_assign.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "odk.h"
|
#include "odk.h"
|
||||||
#include "oemcrypto_engine_ref.h"
|
#include "oemcrypto_engine_ref.h"
|
||||||
#include "oemcrypto_key_ref.h"
|
#include "oemcrypto_key_ref.h"
|
||||||
|
#include "oemcrypto_rsa_key_shared.h"
|
||||||
#include "oemcrypto_types.h"
|
#include "oemcrypto_types.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "string_conversions.h"
|
#include "string_conversions.h"
|
||||||
#include "wvcrc32.h"
|
#include "wvcrc32.h"
|
||||||
|
|
||||||
namespace wvoec_ref {
|
static const int kPssSaltLength = 20;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Increment counter for AES-CTR. The CENC spec specifies we increment only
|
// Increment counter for AES-CTR. The CENC spec specifies we increment only
|
||||||
@@ -63,8 +66,11 @@ void advance_dest_buffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace wvoec_ref {
|
||||||
|
|
||||||
/***************************************/
|
/***************************************/
|
||||||
|
|
||||||
class ContentKeysContext : public SessionContextKeys {
|
class ContentKeysContext : public SessionContextKeys {
|
||||||
@@ -175,17 +181,31 @@ EntitlementKey* EntitlementKeysContext::GetEntitlementKey(
|
|||||||
|
|
||||||
/***************************************/
|
/***************************************/
|
||||||
|
|
||||||
SessionContext::SessionContext(CryptoEngine* ce, SessionId sid)
|
SessionContext::SessionContext(CryptoEngine* ce, SessionId sid,
|
||||||
: valid_(ce != nullptr), ce_(ce), id_(sid) {
|
const RSA_shared_ptr& rsa_key)
|
||||||
|
: valid_(true),
|
||||||
|
ce_(ce),
|
||||||
|
id_(sid),
|
||||||
|
current_content_key_(nullptr),
|
||||||
|
session_keys_(nullptr),
|
||||||
|
license_request_hash_(),
|
||||||
|
rsa_key_(rsa_key),
|
||||||
|
allowed_schemes_(kSign_RSASSA_PSS),
|
||||||
|
decrypt_started_(false),
|
||||||
|
timer_limits_(),
|
||||||
|
clock_values_(),
|
||||||
|
usage_entry_(nullptr),
|
||||||
|
srm_requirements_status_(NoSRMVersion),
|
||||||
|
usage_entry_status_(kNoUsageEntry),
|
||||||
|
compute_hash_(false),
|
||||||
|
current_hash_(0),
|
||||||
|
bad_frame_number_(0),
|
||||||
|
hash_error_(OEMCrypto_SUCCESS),
|
||||||
|
state_nonce_created_(false),
|
||||||
|
state_request_signed_(false),
|
||||||
|
state_response_loaded_(false) {
|
||||||
ODK_InitializeSessionValues(&timer_limits_, &clock_values_, &nonce_values_,
|
ODK_InitializeSessionValues(&timer_limits_, &clock_values_, &nonce_values_,
|
||||||
CryptoEngine::kApiVersion, sid);
|
CryptoEngine::kApiVersion, sid);
|
||||||
memset(license_request_hash_, 0, sizeof(license_request_hash_));
|
|
||||||
}
|
|
||||||
|
|
||||||
SessionContext::SessionContext(CryptoEngine* ce, SessionId sid,
|
|
||||||
std::shared_ptr<RsaPrivateKey>&& rsa_key)
|
|
||||||
: SessionContext(ce, sid) {
|
|
||||||
rsa_key_ = std::move(rsa_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SessionContext::~SessionContext() {}
|
SessionContext::~SessionContext() {}
|
||||||
@@ -238,28 +258,27 @@ bool SessionContext::DeriveKey(const std::vector<uint8_t>& key,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult SessionContext::DeriveKeys(
|
bool SessionContext::DeriveKeys(const std::vector<uint8_t>& master_key,
|
||||||
const std::vector<uint8_t>& master_key,
|
const std::vector<uint8_t>& mac_key_context,
|
||||||
const std::vector<uint8_t>& mac_key_context,
|
const std::vector<uint8_t>& enc_key_context) {
|
||||||
const std::vector<uint8_t>& enc_key_context) {
|
|
||||||
// Generate derived key for mac key
|
// Generate derived key for mac key
|
||||||
std::vector<uint8_t> mac_key_server;
|
std::vector<uint8_t> mac_key_server;
|
||||||
std::vector<uint8_t> mac_key_client;
|
std::vector<uint8_t> mac_key_client;
|
||||||
std::vector<uint8_t> mac_key_part2;
|
std::vector<uint8_t> mac_key_part2;
|
||||||
if (!DeriveKey(master_key, mac_key_context, 1, &mac_key_server)) {
|
if (!DeriveKey(master_key, mac_key_context, 1, &mac_key_server)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return false;
|
||||||
}
|
}
|
||||||
if (!DeriveKey(master_key, mac_key_context, 2, &mac_key_part2)) {
|
if (!DeriveKey(master_key, mac_key_context, 2, &mac_key_part2)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return false;
|
||||||
}
|
}
|
||||||
mac_key_server.insert(mac_key_server.end(), mac_key_part2.begin(),
|
mac_key_server.insert(mac_key_server.end(), mac_key_part2.begin(),
|
||||||
mac_key_part2.end());
|
mac_key_part2.end());
|
||||||
|
|
||||||
if (!DeriveKey(master_key, mac_key_context, 3, &mac_key_client)) {
|
if (!DeriveKey(master_key, mac_key_context, 3, &mac_key_client)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return false;
|
||||||
}
|
}
|
||||||
if (!DeriveKey(master_key, mac_key_context, 4, &mac_key_part2)) {
|
if (!DeriveKey(master_key, mac_key_context, 4, &mac_key_part2)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return false;
|
||||||
}
|
}
|
||||||
mac_key_client.insert(mac_key_client.end(), mac_key_part2.begin(),
|
mac_key_client.insert(mac_key_client.end(), mac_key_part2.begin(),
|
||||||
mac_key_part2.end());
|
mac_key_part2.end());
|
||||||
@@ -267,31 +286,48 @@ OEMCryptoResult SessionContext::DeriveKeys(
|
|||||||
// Generate derived key for encryption key
|
// Generate derived key for encryption key
|
||||||
std::vector<uint8_t> enc_key;
|
std::vector<uint8_t> enc_key;
|
||||||
if (!DeriveKey(master_key, enc_key_context, 1, &enc_key)) {
|
if (!DeriveKey(master_key, enc_key_context, 1, &enc_key)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_mac_key_server(mac_key_server);
|
set_mac_key_server(mac_key_server);
|
||||||
set_mac_key_client(mac_key_client);
|
set_mac_key_client(mac_key_client);
|
||||||
set_encryption_key(enc_key);
|
set_encryption_key(enc_key);
|
||||||
return OEMCrypto_SUCCESS;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult SessionContext::RSADeriveKeys(
|
bool SessionContext::RSADeriveKeys(
|
||||||
const std::vector<uint8_t>& enc_session_key,
|
const std::vector<uint8_t>& enc_session_key,
|
||||||
const std::vector<uint8_t>& mac_key_context,
|
const std::vector<uint8_t>& mac_key_context,
|
||||||
const std::vector<uint8_t>& enc_key_context) {
|
const std::vector<uint8_t>& enc_key_context) {
|
||||||
if (!rsa_key_) {
|
if (!rsa_key()) {
|
||||||
LOGE("No RSA key set");
|
LOGE("[RSADeriveKeys(): no RSA key set]");
|
||||||
return OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(rsa_key_->allowed_schemes() & kSign_RSASSA_PSS)) {
|
const size_t actual_key_size = static_cast<size_t>(RSA_size(rsa_key()));
|
||||||
LOGE("Key cannot be used for session key decryption");
|
if (enc_session_key.size() != actual_key_size) {
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
LOGE(
|
||||||
|
"[RSADeriveKeys(): encrypted session key wrong size: %zu, expected "
|
||||||
|
"%zu]",
|
||||||
|
enc_session_key.size(), actual_key_size);
|
||||||
|
dump_boringssl_error();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
session_key_ = rsa_key_->DecryptSessionKey(enc_session_key);
|
session_key_.resize(RSA_size(rsa_key()));
|
||||||
if (session_key_.empty()) {
|
const int decrypted_size =
|
||||||
LOGE("Failed decrypt session key");
|
RSA_private_decrypt(enc_session_key.size(), &enc_session_key[0],
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
&session_key_[0], rsa_key(), RSA_PKCS1_OAEP_PADDING);
|
||||||
|
if (-1 == decrypted_size) {
|
||||||
|
LOGE("[RSADeriveKeys(): error decrypting session key.]");
|
||||||
|
dump_boringssl_error();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
session_key_.resize(decrypted_size);
|
||||||
|
if (decrypted_size != static_cast<int>(wvoec::KEY_SIZE)) {
|
||||||
|
LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]",
|
||||||
|
decrypted_size);
|
||||||
|
dump_boringssl_error();
|
||||||
|
session_key_.clear();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return DeriveKeys(session_key_, mac_key_context, enc_key_context);
|
return DeriveKeys(session_key_, mac_key_context, enc_key_context);
|
||||||
}
|
}
|
||||||
@@ -300,13 +336,8 @@ OEMCryptoResult SessionContext::PrepAndSignLicenseRequest(
|
|||||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||||
uint8_t* signature, size_t* signature_length) {
|
uint8_t* signature, size_t* signature_length) {
|
||||||
if (signature_length == nullptr || core_message_length == nullptr) {
|
if (signature_length == nullptr || core_message_length == nullptr) {
|
||||||
LOGE("Output length parameters are null");
|
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
if (!rsa_key_) {
|
|
||||||
LOGE("No DRM key available for signature");
|
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
|
||||||
}
|
|
||||||
const size_t required_signature_size = CertSignatureSize();
|
const size_t required_signature_size = CertSignatureSize();
|
||||||
OEMCryptoResult result = ODK_PrepareCoreLicenseRequest(
|
OEMCryptoResult result = ODK_PrepareCoreLicenseRequest(
|
||||||
message, message_length, core_message_length, &nonce_values_);
|
message, message_length, core_message_length, &nonce_values_);
|
||||||
@@ -393,10 +424,6 @@ OEMCryptoResult SessionContext::PrepAndSignProvisioningRequest(
|
|||||||
if (signature_length == nullptr || core_message_length == nullptr) {
|
if (signature_length == nullptr || core_message_length == nullptr) {
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
if (!rsa_key_ && mac_key_client_.empty()) {
|
|
||||||
LOGE("Session cannot sign request");
|
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
|
||||||
}
|
|
||||||
if (state_request_signed_) {
|
if (state_request_signed_) {
|
||||||
LOGE("Attempt to sign prov request after license request");
|
LOGE("Attempt to sign prov request after license request");
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
@@ -461,20 +488,29 @@ OEMCryptoResult SessionContext::GenerateSignature(const uint8_t* message,
|
|||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SessionContext::CertSignatureSize() const {
|
// This is ussd when the device is a cast receiver.
|
||||||
if (!rsa_key_) {
|
size_t SessionContext::RSASignatureSize() {
|
||||||
LOGE("No RSA key set");
|
if (!rsa_key()) {
|
||||||
|
LOGE("no RSA key set");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return rsa_key_->SignatureSize();
|
return static_cast<size_t>(RSA_size(rsa_key()));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SessionContext::ROTSignatureSize() const {
|
size_t SessionContext::CertSignatureSize() {
|
||||||
|
// TODO(b/67735947): Add ECC cert support.
|
||||||
|
if (!rsa_key()) {
|
||||||
|
LOGE("No private key set");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return static_cast<size_t>(RSA_size(rsa_key()));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SessionContext::ROTSignatureSize() {
|
||||||
if (ce_->config_provisioning_method() == OEMCrypto_Keybox)
|
if (ce_->config_provisioning_method() == OEMCrypto_Keybox)
|
||||||
return SHA256_DIGEST_LENGTH;
|
return SHA256_DIGEST_LENGTH;
|
||||||
if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate) {
|
if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate)
|
||||||
return CertSignatureSize();
|
return CertSignatureSize();
|
||||||
}
|
|
||||||
LOGE("Bad prov method = %d",
|
LOGE("Bad prov method = %d",
|
||||||
static_cast<int>(ce_->config_provisioning_method()));
|
static_cast<int>(ce_->config_provisioning_method()));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -483,27 +519,92 @@ size_t SessionContext::ROTSignatureSize() const {
|
|||||||
OEMCryptoResult SessionContext::GenerateCertSignature(
|
OEMCryptoResult SessionContext::GenerateCertSignature(
|
||||||
const uint8_t* message, size_t message_length, uint8_t* signature,
|
const uint8_t* message, size_t message_length, uint8_t* signature,
|
||||||
size_t* signature_length) {
|
size_t* signature_length) {
|
||||||
if (!rsa_key_) {
|
// TODO(b/67735947): Add ECC cert support.
|
||||||
|
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
||||||
|
signature_length == 0) {
|
||||||
|
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
||||||
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
|
}
|
||||||
|
if (!rsa_key()) {
|
||||||
LOGE("No RSA key set");
|
LOGE("No RSA key set");
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
return rsa_key_->GenerateSignature(message, message_length, kRsaPssDefault,
|
if (*signature_length < static_cast<size_t>(RSA_size(rsa_key()))) {
|
||||||
signature, signature_length);
|
*signature_length = CertSignatureSize();
|
||||||
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
|
}
|
||||||
|
if (allowed_schemes_ != kSign_RSASSA_PSS) {
|
||||||
|
LOGE("Message signing not allowed");
|
||||||
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash the message using SHA1.
|
||||||
|
uint8_t hash[SHA_DIGEST_LENGTH];
|
||||||
|
if (!SHA1(message, message_length, hash)) {
|
||||||
|
LOGE("Error creating signature hash");
|
||||||
|
dump_boringssl_error();
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add PSS padding.
|
||||||
|
std::vector<uint8_t> padded_digest(*signature_length);
|
||||||
|
int status = RSA_padding_add_PKCS1_PSS_mgf1(
|
||||||
|
rsa_key(), &padded_digest[0], hash, EVP_sha1(), nullptr, kPssSaltLength);
|
||||||
|
if (status == -1) {
|
||||||
|
LOGE("Error padding hash");
|
||||||
|
dump_boringssl_error();
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypt PSS padded digest.
|
||||||
|
status = RSA_private_encrypt(*signature_length, &padded_digest[0], signature,
|
||||||
|
rsa_key(), RSA_NO_PADDING);
|
||||||
|
if (status == -1) {
|
||||||
|
LOGE("Error in private encrypt");
|
||||||
|
dump_boringssl_error();
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult SessionContext::GenerateRSASignature(
|
OEMCryptoResult SessionContext::GenerateRSASignature(
|
||||||
const uint8_t* message, size_t message_length, uint8_t* signature,
|
const uint8_t* message, size_t message_length, uint8_t* signature,
|
||||||
size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
|
size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
|
||||||
if (padding_scheme != kSign_PKCS1_Block1) {
|
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
||||||
LOGE("Only PKCS1 block1 padding scheme allowed");
|
signature_length == 0) {
|
||||||
|
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
if (!rsa_key_) {
|
if (!rsa_key()) {
|
||||||
LOGE("No RSA key set");
|
LOGE("No RSA key set");
|
||||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
}
|
}
|
||||||
return rsa_key_->GenerateSignature(message, message_length, kRsaPkcs1Cast,
|
if (*signature_length < static_cast<size_t>(RSA_size(rsa_key()))) {
|
||||||
signature, signature_length);
|
*signature_length = RSA_size(rsa_key());
|
||||||
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
||||||
|
}
|
||||||
|
if (((padding_scheme & allowed_schemes_) != padding_scheme) ||
|
||||||
|
(padding_scheme != kSign_PKCS1_Block1)) {
|
||||||
|
LOGE("padding_scheme not allowed");
|
||||||
|
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||||
|
}
|
||||||
|
// This is the maximum digest size possible for PKCS1 block type 1,
|
||||||
|
// as used for a CAST receiver.
|
||||||
|
const size_t max_digest_size = 83u;
|
||||||
|
if (message_length > max_digest_size) {
|
||||||
|
LOGE("RSA digest too large");
|
||||||
|
return OEMCrypto_ERROR_SIGNATURE_FAILURE;
|
||||||
|
}
|
||||||
|
// Pad the message with PKCS1 padding, and then encrypt.
|
||||||
|
const int status = RSA_private_encrypt(message_length, message, signature,
|
||||||
|
rsa_key(), RSA_PKCS1_PADDING);
|
||||||
|
if (status < 0) {
|
||||||
|
LOGE("Error in RSA private encrypt. status = %d", status);
|
||||||
|
dump_boringssl_error();
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
|
*signature_length = static_cast<size_t>(RSA_size(rsa_key()));
|
||||||
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate message signature
|
// Validate message signature
|
||||||
@@ -933,19 +1034,24 @@ OEMCryptoResult SessionContext::InstallKey(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SessionContext::InstallRSAEncryptedKey(
|
bool SessionContext::InstallRSAEncryptedKey(
|
||||||
const std::vector<uint8_t>& enc_encryption_key) {
|
const uint8_t* encrypted_message_key, size_t encrypted_message_key_length) {
|
||||||
if (!rsa_key_) {
|
encryption_key_.resize(RSA_size(rsa_key()));
|
||||||
LOGE("Session does not have an OEM cert key");
|
const int decrypted_size = RSA_private_decrypt(
|
||||||
|
encrypted_message_key_length, encrypted_message_key, &encryption_key_[0],
|
||||||
|
rsa_key(), RSA_PKCS1_OAEP_PADDING);
|
||||||
|
if (-1 == decrypted_size) {
|
||||||
|
LOGE("[RSADeriveKeys(): error decrypting session key.]");
|
||||||
|
dump_boringssl_error();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
encryption_key_.resize(decrypted_size);
|
||||||
std::vector<uint8_t> encryption_key =
|
if (decrypted_size != static_cast<int>(wvoec::KEY_SIZE)) {
|
||||||
rsa_key_->DecryptEncryptionKey(enc_encryption_key);
|
LOGE("[RSADeriveKeys(): error. Session key is wrong size: %d.]",
|
||||||
if (encryption_key.empty()) {
|
decrypted_size);
|
||||||
LOGE("Failed to decrypt session encryption key");
|
dump_boringssl_error();
|
||||||
|
encryption_key_.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
encryption_key_ = std::move(encryption_key);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1056,23 +1162,23 @@ bool SessionContext::EncryptRSAKey(const uint8_t* pkcs8_rsa_key,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionContext::LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key,
|
bool SessionContext::LoadRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||||
size_t rsa_key_length) {
|
size_t rsa_key_length) {
|
||||||
std::unique_ptr<RsaPrivateKey> key =
|
rsa_key_.reset();
|
||||||
RsaPrivateKey::Load(pkcs8_rsa_key, rsa_key_length);
|
if (rsa_key_length < 8) {
|
||||||
if (!key) {
|
LOGE("[LoadRSAKey(): Very Short Buffer]");
|
||||||
LOGE("Failed to parse RSA key");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
constexpr uint8_t kAllSchemes = kSign_RSASSA_PSS | kSign_PKCS1_Block1;
|
if ((memcmp(pkcs8_rsa_key, "SIGN", 4) == 0)) {
|
||||||
if (key->allowed_schemes() == 0 ||
|
uint32_t schemes_n;
|
||||||
(key->allowed_schemes() & kAllSchemes) == kAllSchemes) {
|
memcpy((uint8_t*)&schemes_n, pkcs8_rsa_key + 4, sizeof(uint32_t));
|
||||||
LOGE("RSA DRM key has an invalid set of schemes: allowed_schemes = 0x%08x",
|
allowed_schemes_ = htonl(schemes_n);
|
||||||
key->allowed_schemes());
|
pkcs8_rsa_key += 8;
|
||||||
return false;
|
rsa_key_length -= 8;
|
||||||
|
} else {
|
||||||
|
allowed_schemes_ = kSign_RSASSA_PSS;
|
||||||
}
|
}
|
||||||
rsa_key_ = std::move(key);
|
return rsa_key_.LoadPkcs8RsaKey(pkcs8_rsa_key, rsa_key_length);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
|
OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
|
||||||
@@ -1255,6 +1361,7 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer,
|
|||||||
return OEMCrypto_SUCCESS;
|
return OEMCrypto_SUCCESS;
|
||||||
}
|
}
|
||||||
LOGE("[Generic_Sign(): hmac failed");
|
LOGE("[Generic_Sign(): hmac failed");
|
||||||
|
dump_boringssl_error();
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,6 +1402,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOGE("[Generic_Verify(): HMAC failed");
|
LOGE("[Generic_Verify(): HMAC failed");
|
||||||
|
dump_boringssl_error();
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "odk_structs.h"
|
#include "odk_structs.h"
|
||||||
#include "oemcrypto_auth_ref.h"
|
#include "oemcrypto_auth_ref.h"
|
||||||
#include "oemcrypto_key_ref.h"
|
#include "oemcrypto_key_ref.h"
|
||||||
#include "oemcrypto_rsa_key.h"
|
#include "oemcrypto_rsa_key_shared.h"
|
||||||
#include "oemcrypto_session_key_table.h"
|
#include "oemcrypto_session_key_table.h"
|
||||||
#include "oemcrypto_types.h"
|
#include "oemcrypto_types.h"
|
||||||
#include "oemcrypto_usage_table_ref.h"
|
#include "oemcrypto_usage_table_ref.h"
|
||||||
@@ -59,22 +59,21 @@ class SessionContextKeys {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class SessionContext {
|
class SessionContext {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SessionContext(CryptoEngine* ce, SessionId sid);
|
|
||||||
SessionContext(CryptoEngine* ce, SessionId sid,
|
SessionContext(CryptoEngine* ce, SessionId sid,
|
||||||
std::shared_ptr<RsaPrivateKey>&& rsa_key);
|
const RSA_shared_ptr& rsa_key);
|
||||||
SessionContext() = delete;
|
SessionContext() = delete;
|
||||||
virtual ~SessionContext();
|
virtual ~SessionContext();
|
||||||
|
|
||||||
bool isValid() const { return valid_; }
|
bool isValid() { return valid_; }
|
||||||
|
|
||||||
virtual OEMCryptoResult DeriveKeys(const std::vector<uint8_t>& master_key,
|
virtual bool DeriveKeys(const std::vector<uint8_t>& master_key,
|
||||||
const std::vector<uint8_t>& mac_context,
|
const std::vector<uint8_t>& mac_context,
|
||||||
const std::vector<uint8_t>& enc_context);
|
const std::vector<uint8_t>& enc_context);
|
||||||
virtual OEMCryptoResult RSADeriveKeys(
|
virtual bool RSADeriveKeys(const std::vector<uint8_t>& enc_session_key,
|
||||||
const std::vector<uint8_t>& enc_session_key,
|
const std::vector<uint8_t>& mac_context,
|
||||||
const std::vector<uint8_t>& mac_context,
|
const std::vector<uint8_t>& enc_context);
|
||||||
const std::vector<uint8_t>& enc_context);
|
|
||||||
virtual OEMCryptoResult PrepAndSignLicenseRequest(uint8_t* message,
|
virtual OEMCryptoResult PrepAndSignLicenseRequest(uint8_t* message,
|
||||||
size_t message_length,
|
size_t message_length,
|
||||||
size_t* core_message_length,
|
size_t* core_message_length,
|
||||||
@@ -88,7 +87,9 @@ class SessionContext {
|
|||||||
virtual OEMCryptoResult PrepAndSignProvisioningRequest(
|
virtual OEMCryptoResult PrepAndSignProvisioningRequest(
|
||||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||||
uint8_t* signature, size_t* signature_length);
|
uint8_t* signature, size_t* signature_length);
|
||||||
// Restricted to CAST receivers using PKCS1 block padding only.
|
// The size of an RSA signature. This is used when signing as a CAST
|
||||||
|
// receiver.
|
||||||
|
size_t RSASignatureSize();
|
||||||
virtual OEMCryptoResult GenerateRSASignature(
|
virtual OEMCryptoResult GenerateRSASignature(
|
||||||
const uint8_t* message, size_t message_length, uint8_t* signature,
|
const uint8_t* message, size_t message_length, uint8_t* signature,
|
||||||
size_t* signature_length, RSA_Padding_Scheme padding_scheme);
|
size_t* signature_length, RSA_Padding_Scheme padding_scheme);
|
||||||
@@ -140,12 +141,13 @@ class SessionContext {
|
|||||||
const std::vector<uint8_t>& key_data_iv,
|
const std::vector<uint8_t>& key_data_iv,
|
||||||
const std::vector<uint8_t>& key_control,
|
const std::vector<uint8_t>& key_control,
|
||||||
const std::vector<uint8_t>& key_control_iv);
|
const std::vector<uint8_t>& key_control_iv);
|
||||||
bool InstallRSAEncryptedKey(const std::vector<uint8_t>& enc_encryption_key);
|
bool InstallRSAEncryptedKey(const uint8_t* encrypted_message_key,
|
||||||
|
size_t encrypted_message_key_length);
|
||||||
bool DecryptRSAKey(const uint8_t* enc_rsa_key, size_t enc_rsa_key_length,
|
bool DecryptRSAKey(const uint8_t* enc_rsa_key, size_t enc_rsa_key_length,
|
||||||
const uint8_t* wrapped_rsa_key_iv, uint8_t* pkcs8_rsa_key);
|
const uint8_t* wrapped_rsa_key_iv, uint8_t* pkcs8_rsa_key);
|
||||||
bool EncryptRSAKey(const uint8_t* pkcs8_rsa_key, size_t enc_rsa_key_length,
|
bool EncryptRSAKey(const uint8_t* pkcs8_rsa_key, size_t enc_rsa_key_length,
|
||||||
const uint8_t* enc_rsa_key_iv, uint8_t* enc_rsa_key);
|
const uint8_t* enc_rsa_key_iv, uint8_t* enc_rsa_key);
|
||||||
bool LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length);
|
bool LoadRSAKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length);
|
||||||
virtual OEMCryptoResult LoadRenewal(const uint8_t* message,
|
virtual OEMCryptoResult LoadRenewal(const uint8_t* message,
|
||||||
size_t message_length,
|
size_t message_length,
|
||||||
size_t core_message_length,
|
size_t core_message_length,
|
||||||
@@ -177,6 +179,7 @@ class SessionContext {
|
|||||||
encryption_key_ = enc_key;
|
encryption_key_ = enc_key;
|
||||||
}
|
}
|
||||||
const std::vector<uint8_t>& encryption_key() { return encryption_key_; }
|
const std::vector<uint8_t>& encryption_key() { return encryption_key_; }
|
||||||
|
uint32_t allowed_schemes() const { return allowed_schemes_; }
|
||||||
|
|
||||||
// Return true if nonce was set.
|
// Return true if nonce was set.
|
||||||
bool set_nonce(uint32_t nonce);
|
bool set_nonce(uint32_t nonce);
|
||||||
@@ -202,9 +205,9 @@ class SessionContext {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Signature size of the currently loaded private key.
|
// Signature size of the currently loaded private key.
|
||||||
size_t CertSignatureSize() const;
|
size_t CertSignatureSize();
|
||||||
// Signature size when using a keybox or OEM Cert's private key.
|
// Signature size when using a keybox or OEM Cert's private key.
|
||||||
size_t ROTSignatureSize() const;
|
size_t ROTSignatureSize();
|
||||||
virtual OEMCryptoResult GenerateCertSignature(const uint8_t* message,
|
virtual OEMCryptoResult GenerateCertSignature(const uint8_t* message,
|
||||||
size_t message_length,
|
size_t message_length,
|
||||||
uint8_t* signature,
|
uint8_t* signature,
|
||||||
@@ -254,52 +257,46 @@ class SessionContext {
|
|||||||
// entry, it also checks the usage entry.
|
// entry, it also checks the usage entry.
|
||||||
OEMCryptoResult CheckKeyUse(const std::string& log_string, uint32_t use_type,
|
OEMCryptoResult CheckKeyUse(const std::string& log_string, uint32_t use_type,
|
||||||
OEMCryptoBufferType buffer_type);
|
OEMCryptoBufferType buffer_type);
|
||||||
|
RSA* rsa_key() { return rsa_key_.get(); }
|
||||||
|
|
||||||
bool valid_ = false;
|
bool valid_;
|
||||||
CryptoEngine* ce_ = nullptr;
|
CryptoEngine* ce_;
|
||||||
SessionId id_;
|
SessionId id_;
|
||||||
|
|
||||||
// Message keys.
|
|
||||||
std::shared_ptr<RsaPrivateKey> rsa_key_;
|
|
||||||
std::vector<uint8_t> mac_key_server_;
|
std::vector<uint8_t> mac_key_server_;
|
||||||
std::vector<uint8_t> mac_key_client_;
|
std::vector<uint8_t> mac_key_client_;
|
||||||
std::vector<uint8_t> encryption_key_;
|
std::vector<uint8_t> encryption_key_;
|
||||||
std::vector<uint8_t> session_key_;
|
std::vector<uint8_t> session_key_;
|
||||||
|
const Key* current_content_key_;
|
||||||
|
std::unique_ptr<SessionContextKeys> session_keys_;
|
||||||
ODK_NonceValues nonce_values_;
|
ODK_NonceValues nonce_values_;
|
||||||
uint8_t license_request_hash_[ODK_SHA256_HASH_SIZE];
|
uint8_t license_request_hash_[ODK_SHA256_HASH_SIZE];
|
||||||
|
RSA_shared_ptr rsa_key_;
|
||||||
// Content/entitlement keys.
|
uint32_t allowed_schemes_; // for RSA signatures.
|
||||||
const Key* current_content_key_ = nullptr;
|
bool decrypt_started_; // If the license has been used in this session.
|
||||||
std::unique_ptr<SessionContextKeys> session_keys_;
|
|
||||||
|
|
||||||
bool decrypt_started_ =
|
|
||||||
false; // If the license has been used in this session.
|
|
||||||
ODK_TimerLimits timer_limits_;
|
ODK_TimerLimits timer_limits_;
|
||||||
ODK_ClockValues clock_values_;
|
ODK_ClockValues clock_values_;
|
||||||
std::unique_ptr<UsageTableEntry> usage_entry_;
|
std::unique_ptr<UsageTableEntry> usage_entry_;
|
||||||
SRMVersionStatus srm_requirements_status_ = NoSRMVersion;
|
SRMVersionStatus srm_requirements_status_;
|
||||||
enum UsageEntryStatus {
|
enum UsageEntryStatus {
|
||||||
kNoUsageEntry, // No entry loaded for this session.
|
kNoUsageEntry, // No entry loaded for this session.
|
||||||
kUsageEntryNew, // After entry was created.
|
kUsageEntryNew, // After entry was created.
|
||||||
kUsageEntryLoaded, // After loading entry or loading keys.
|
kUsageEntryLoaded, // After loading entry or loading keys.
|
||||||
};
|
};
|
||||||
UsageEntryStatus usage_entry_status_ = kNoUsageEntry;
|
UsageEntryStatus usage_entry_status_;
|
||||||
|
|
||||||
// These are used when doing full decrypt path testing.
|
// These are used when doing full decrypt path testing.
|
||||||
bool compute_hash_ = false; // True if the current frame needs a hash.
|
bool compute_hash_; // True if the current frame needs a hash.
|
||||||
uint32_t current_hash_ = 0; // Running CRC hash of frame.
|
uint32_t current_hash_; // Running CRC hash of frame.
|
||||||
uint32_t given_hash_ = 0; // True CRC hash of frame.
|
uint32_t given_hash_; // True CRC hash of frame.
|
||||||
uint32_t current_frame_number_ = 0; // Current frame for CRC hash.
|
uint32_t current_frame_number_; // Current frame for CRC hash.
|
||||||
uint32_t bad_frame_number_ = 0; // Frame number with bad hash.
|
uint32_t bad_frame_number_; // Frame number with bad hash.
|
||||||
OEMCryptoResult hash_error_ =
|
OEMCryptoResult hash_error_; // Error code for first bad frame.
|
||||||
OEMCrypto_SUCCESS; // Error code for first bad frame.
|
|
||||||
|
|
||||||
// The bare minimum state machine is to only call each of these function
|
// The bare minimum state machine is to only call each of these function
|
||||||
// categories at most once.
|
// categories at most once.
|
||||||
bool state_nonce_created_ = false;
|
bool state_nonce_created_;
|
||||||
bool state_request_signed_ = false;
|
bool state_request_signed_;
|
||||||
bool state_response_loaded_ = false;
|
bool state_response_loaded_;
|
||||||
|
|
||||||
CORE_DISALLOW_COPY_AND_ASSIGN(SessionContext);
|
CORE_DISALLOW_COPY_AND_ASSIGN(SessionContext);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user