[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:
@@ -25,17 +25,20 @@
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "advance_iv_ctr.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "keys.h"
|
||||
#include "log.h"
|
||||
#include "odk.h"
|
||||
#include "oemcrypto_engine_ref.h"
|
||||
#include "oemcrypto_key_ref.h"
|
||||
#include "oemcrypto_rsa_key_shared.h"
|
||||
#include "oemcrypto_types.h"
|
||||
#include "platform.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wvcrc32.h"
|
||||
|
||||
namespace wvoec_ref {
|
||||
static const int kPssSaltLength = 20;
|
||||
|
||||
namespace {
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvoec_ref {
|
||||
|
||||
/***************************************/
|
||||
|
||||
class ContentKeysContext : public SessionContextKeys {
|
||||
@@ -175,17 +181,31 @@ EntitlementKey* EntitlementKeysContext::GetEntitlementKey(
|
||||
|
||||
/***************************************/
|
||||
|
||||
SessionContext::SessionContext(CryptoEngine* ce, SessionId sid)
|
||||
: valid_(ce != nullptr), ce_(ce), id_(sid) {
|
||||
SessionContext::SessionContext(CryptoEngine* ce, SessionId 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_,
|
||||
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() {}
|
||||
@@ -238,28 +258,27 @@ bool SessionContext::DeriveKey(const std::vector<uint8_t>& key,
|
||||
return true;
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::DeriveKeys(
|
||||
const std::vector<uint8_t>& master_key,
|
||||
const std::vector<uint8_t>& mac_key_context,
|
||||
const std::vector<uint8_t>& enc_key_context) {
|
||||
bool SessionContext::DeriveKeys(const std::vector<uint8_t>& master_key,
|
||||
const std::vector<uint8_t>& mac_key_context,
|
||||
const std::vector<uint8_t>& enc_key_context) {
|
||||
// Generate derived key for mac key
|
||||
std::vector<uint8_t> mac_key_server;
|
||||
std::vector<uint8_t> mac_key_client;
|
||||
std::vector<uint8_t> mac_key_part2;
|
||||
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)) {
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
return false;
|
||||
}
|
||||
mac_key_server.insert(mac_key_server.end(), mac_key_part2.begin(),
|
||||
mac_key_part2.end());
|
||||
|
||||
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)) {
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
return false;
|
||||
}
|
||||
mac_key_client.insert(mac_key_client.end(), mac_key_part2.begin(),
|
||||
mac_key_part2.end());
|
||||
@@ -267,31 +286,48 @@ OEMCryptoResult SessionContext::DeriveKeys(
|
||||
// Generate derived key for encryption key
|
||||
std::vector<uint8_t> 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_client(mac_key_client);
|
||||
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>& mac_key_context,
|
||||
const std::vector<uint8_t>& enc_key_context) {
|
||||
if (!rsa_key_) {
|
||||
LOGE("No RSA key set");
|
||||
return OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED;
|
||||
if (!rsa_key()) {
|
||||
LOGE("[RSADeriveKeys(): no RSA key set]");
|
||||
return false;
|
||||
}
|
||||
if (!(rsa_key_->allowed_schemes() & kSign_RSASSA_PSS)) {
|
||||
LOGE("Key cannot be used for session key decryption");
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
const size_t actual_key_size = static_cast<size_t>(RSA_size(rsa_key()));
|
||||
if (enc_session_key.size() != actual_key_size) {
|
||||
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);
|
||||
if (session_key_.empty()) {
|
||||
LOGE("Failed decrypt session key");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
session_key_.resize(RSA_size(rsa_key()));
|
||||
const int decrypted_size =
|
||||
RSA_private_decrypt(enc_session_key.size(), &enc_session_key[0],
|
||||
&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);
|
||||
}
|
||||
@@ -300,13 +336,8 @@ OEMCryptoResult SessionContext::PrepAndSignLicenseRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
uint8_t* signature, size_t* signature_length) {
|
||||
if (signature_length == nullptr || core_message_length == nullptr) {
|
||||
LOGE("Output length parameters are null");
|
||||
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();
|
||||
OEMCryptoResult result = ODK_PrepareCoreLicenseRequest(
|
||||
message, message_length, core_message_length, &nonce_values_);
|
||||
@@ -393,10 +424,6 @@ OEMCryptoResult SessionContext::PrepAndSignProvisioningRequest(
|
||||
if (signature_length == nullptr || core_message_length == nullptr) {
|
||||
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_) {
|
||||
LOGE("Attempt to sign prov request after license request");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
@@ -461,20 +488,29 @@ OEMCryptoResult SessionContext::GenerateSignature(const uint8_t* message,
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
size_t SessionContext::CertSignatureSize() const {
|
||||
if (!rsa_key_) {
|
||||
LOGE("No RSA key set");
|
||||
// This is ussd when the device is a cast receiver.
|
||||
size_t SessionContext::RSASignatureSize() {
|
||||
if (!rsa_key()) {
|
||||
LOGE("no RSA key set");
|
||||
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)
|
||||
return SHA256_DIGEST_LENGTH;
|
||||
if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate) {
|
||||
if (ce_->config_provisioning_method() == OEMCrypto_OEMCertificate)
|
||||
return CertSignatureSize();
|
||||
}
|
||||
LOGE("Bad prov method = %d",
|
||||
static_cast<int>(ce_->config_provisioning_method()));
|
||||
return 0;
|
||||
@@ -483,27 +519,92 @@ size_t SessionContext::ROTSignatureSize() const {
|
||||
OEMCryptoResult SessionContext::GenerateCertSignature(
|
||||
const uint8_t* message, size_t message_length, uint8_t* signature,
|
||||
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");
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
return rsa_key_->GenerateSignature(message, message_length, kRsaPssDefault,
|
||||
signature, signature_length);
|
||||
if (*signature_length < static_cast<size_t>(RSA_size(rsa_key()))) {
|
||||
*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(
|
||||
const uint8_t* message, size_t message_length, uint8_t* signature,
|
||||
size_t* signature_length, RSA_Padding_Scheme padding_scheme) {
|
||||
if (padding_scheme != kSign_PKCS1_Block1) {
|
||||
LOGE("Only PKCS1 block1 padding scheme allowed");
|
||||
if (message == nullptr || message_length == 0 || signature == nullptr ||
|
||||
signature_length == 0) {
|
||||
LOGE("OEMCrypto_ERROR_INVALID_CONTEXT");
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
if (!rsa_key_) {
|
||||
if (!rsa_key()) {
|
||||
LOGE("No RSA key set");
|
||||
return OEMCrypto_ERROR_INVALID_RSA_KEY;
|
||||
}
|
||||
return rsa_key_->GenerateSignature(message, message_length, kRsaPkcs1Cast,
|
||||
signature, signature_length);
|
||||
if (*signature_length < static_cast<size_t>(RSA_size(rsa_key()))) {
|
||||
*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
|
||||
@@ -933,19 +1034,24 @@ OEMCryptoResult SessionContext::InstallKey(
|
||||
}
|
||||
|
||||
bool SessionContext::InstallRSAEncryptedKey(
|
||||
const std::vector<uint8_t>& enc_encryption_key) {
|
||||
if (!rsa_key_) {
|
||||
LOGE("Session does not have an OEM cert key");
|
||||
const uint8_t* encrypted_message_key, size_t encrypted_message_key_length) {
|
||||
encryption_key_.resize(RSA_size(rsa_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;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> encryption_key =
|
||||
rsa_key_->DecryptEncryptionKey(enc_encryption_key);
|
||||
if (encryption_key.empty()) {
|
||||
LOGE("Failed to decrypt session encryption key");
|
||||
encryption_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();
|
||||
encryption_key_.clear();
|
||||
return false;
|
||||
}
|
||||
encryption_key_ = std::move(encryption_key);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1056,23 +1162,23 @@ bool SessionContext::EncryptRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionContext::LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key,
|
||||
size_t rsa_key_length) {
|
||||
std::unique_ptr<RsaPrivateKey> key =
|
||||
RsaPrivateKey::Load(pkcs8_rsa_key, rsa_key_length);
|
||||
if (!key) {
|
||||
LOGE("Failed to parse RSA key");
|
||||
bool SessionContext::LoadRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||
size_t rsa_key_length) {
|
||||
rsa_key_.reset();
|
||||
if (rsa_key_length < 8) {
|
||||
LOGE("[LoadRSAKey(): Very Short Buffer]");
|
||||
return false;
|
||||
}
|
||||
constexpr uint8_t kAllSchemes = kSign_RSASSA_PSS | kSign_PKCS1_Block1;
|
||||
if (key->allowed_schemes() == 0 ||
|
||||
(key->allowed_schemes() & kAllSchemes) == kAllSchemes) {
|
||||
LOGE("RSA DRM key has an invalid set of schemes: allowed_schemes = 0x%08x",
|
||||
key->allowed_schemes());
|
||||
return false;
|
||||
if ((memcmp(pkcs8_rsa_key, "SIGN", 4) == 0)) {
|
||||
uint32_t schemes_n;
|
||||
memcpy((uint8_t*)&schemes_n, pkcs8_rsa_key + 4, sizeof(uint32_t));
|
||||
allowed_schemes_ = htonl(schemes_n);
|
||||
pkcs8_rsa_key += 8;
|
||||
rsa_key_length -= 8;
|
||||
} else {
|
||||
allowed_schemes_ = kSign_RSASSA_PSS;
|
||||
}
|
||||
rsa_key_ = std::move(key);
|
||||
return true;
|
||||
return rsa_key_.LoadPkcs8RsaKey(pkcs8_rsa_key, rsa_key_length);
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::CheckKeyUse(const std::string& log_string,
|
||||
@@ -1255,6 +1361,7 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer,
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
LOGE("[Generic_Sign(): hmac failed");
|
||||
dump_boringssl_error();
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1295,6 +1402,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
|
||||
}
|
||||
}
|
||||
LOGE("[Generic_Verify(): HMAC failed");
|
||||
dump_boringssl_error();
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user