Restructed reference root of trust (2/3 DRM Cert)

[ Merge of http://go/wvgerrit/115551 ]

This change is the second part of a three part change for restructing
the root of trust used by the reference implementation.

The use of RSA_shared_ptr has been replaced with the standard library
std::shared_ptr using the RsaPrivateKey wrapper class.  The
AuthenticationRoot class now uses this for the built-in DRM cert key.

RSA decryption and signature operations within the session context are
now performed the RsaPrivateKey class.  This has reduced the code size
and complexity within the reference and testbed, focusing their
implementation on key policy and less on mechanics.

Bug: 168544740
Bug: 135283522
Test: oemcrypto_unittests ce_cdm_tests
Change-Id: Ic743a529a9858f3182290d8bcf5e1633737b005b
This commit is contained in:
Alex Dale
2021-02-18 19:53:12 -08:00
parent e4ee4eb404
commit f6f5099604
11 changed files with 187 additions and 458 deletions

View File

@@ -18,7 +18,7 @@
#include "odk_structs.h"
#include "oemcrypto_auth_ref.h"
#include "oemcrypto_key_ref.h"
#include "oemcrypto_rsa_key_shared.h"
#include "oemcrypto_rsa_key.h"
#include "oemcrypto_session_key_table.h"
#include "oemcrypto_types.h"
#include "oemcrypto_usage_table_ref.h"
@@ -59,21 +59,22 @@ class SessionContextKeys {
};
class SessionContext {
public:
SessionContext(CryptoEngine* ce, SessionId sid);
SessionContext(CryptoEngine* ce, SessionId sid,
const RSA_shared_ptr& rsa_key);
std::shared_ptr<RsaPrivateKey>&& rsa_key);
SessionContext() = delete;
virtual ~SessionContext();
bool isValid() { return valid_; }
bool isValid() const { return valid_; }
virtual bool DeriveKeys(const std::vector<uint8_t>& master_key,
const std::vector<uint8_t>& mac_context,
const std::vector<uint8_t>& enc_context);
virtual bool RSADeriveKeys(const std::vector<uint8_t>& enc_session_key,
const std::vector<uint8_t>& mac_context,
const std::vector<uint8_t>& enc_context);
virtual OEMCryptoResult DeriveKeys(const std::vector<uint8_t>& master_key,
const std::vector<uint8_t>& mac_context,
const std::vector<uint8_t>& enc_context);
virtual OEMCryptoResult RSADeriveKeys(
const std::vector<uint8_t>& enc_session_key,
const std::vector<uint8_t>& mac_context,
const std::vector<uint8_t>& enc_context);
virtual OEMCryptoResult PrepAndSignLicenseRequest(uint8_t* message,
size_t message_length,
size_t* core_message_length,
@@ -87,9 +88,7 @@ class SessionContext {
virtual OEMCryptoResult PrepAndSignProvisioningRequest(
uint8_t* message, size_t message_length, size_t* core_message_length,
uint8_t* signature, size_t* signature_length);
// The size of an RSA signature. This is used when signing as a CAST
// receiver.
size_t RSASignatureSize();
// Restricted to CAST receivers using PKCS1 block padding only.
virtual OEMCryptoResult GenerateRSASignature(
const uint8_t* message, size_t message_length, uint8_t* signature,
size_t* signature_length, RSA_Padding_Scheme padding_scheme);
@@ -141,13 +140,12 @@ class SessionContext {
const std::vector<uint8_t>& key_data_iv,
const std::vector<uint8_t>& key_control,
const std::vector<uint8_t>& key_control_iv);
bool InstallRSAEncryptedKey(const uint8_t* encrypted_message_key,
size_t encrypted_message_key_length);
bool InstallRSAEncryptedKey(const std::vector<uint8_t>& enc_encryption_key);
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);
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);
bool LoadRSAKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length);
bool LoadRsaDrmKey(const uint8_t* pkcs8_rsa_key, size_t rsa_key_length);
virtual OEMCryptoResult LoadRenewal(const uint8_t* message,
size_t message_length,
size_t core_message_length,
@@ -179,7 +177,6 @@ class SessionContext {
encryption_key_ = enc_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.
bool set_nonce(uint32_t nonce);
@@ -205,9 +202,9 @@ class SessionContext {
protected:
// Signature size of the currently loaded private key.
size_t CertSignatureSize();
size_t CertSignatureSize() const;
// Signature size when using a keybox or OEM Cert's private key.
size_t ROTSignatureSize();
size_t ROTSignatureSize() const;
virtual OEMCryptoResult GenerateCertSignature(const uint8_t* message,
size_t message_length,
uint8_t* signature,
@@ -257,46 +254,52 @@ class SessionContext {
// entry, it also checks the usage entry.
OEMCryptoResult CheckKeyUse(const std::string& log_string, uint32_t use_type,
OEMCryptoBufferType buffer_type);
RSA* rsa_key() { return rsa_key_.get(); }
bool valid_;
CryptoEngine* ce_;
bool valid_ = false;
CryptoEngine* ce_ = nullptr;
SessionId id_;
// Message keys.
std::shared_ptr<RsaPrivateKey> rsa_key_;
std::vector<uint8_t> mac_key_server_;
std::vector<uint8_t> mac_key_client_;
std::vector<uint8_t> encryption_key_;
std::vector<uint8_t> session_key_;
const Key* current_content_key_;
std::unique_ptr<SessionContextKeys> session_keys_;
ODK_NonceValues nonce_values_;
uint8_t license_request_hash_[ODK_SHA256_HASH_SIZE];
RSA_shared_ptr rsa_key_;
uint32_t allowed_schemes_; // for RSA signatures.
bool decrypt_started_; // If the license has been used in this session.
// Content/entitlement keys.
const Key* current_content_key_ = nullptr;
std::unique_ptr<SessionContextKeys> session_keys_;
bool decrypt_started_ =
false; // If the license has been used in this session.
ODK_TimerLimits timer_limits_;
ODK_ClockValues clock_values_;
std::unique_ptr<UsageTableEntry> usage_entry_;
SRMVersionStatus srm_requirements_status_;
SRMVersionStatus srm_requirements_status_ = NoSRMVersion;
enum UsageEntryStatus {
kNoUsageEntry, // No entry loaded for this session.
kUsageEntryNew, // After entry was created.
kUsageEntryLoaded, // After loading entry or loading keys.
};
UsageEntryStatus usage_entry_status_;
UsageEntryStatus usage_entry_status_ = kNoUsageEntry;
// These are used when doing full decrypt path testing.
bool compute_hash_; // True if the current frame needs a hash.
uint32_t current_hash_; // Running CRC hash of frame.
uint32_t given_hash_; // True CRC hash of frame.
uint32_t current_frame_number_; // Current frame for CRC hash.
uint32_t bad_frame_number_; // Frame number with bad hash.
OEMCryptoResult hash_error_; // Error code for first bad frame.
bool compute_hash_ = false; // True if the current frame needs a hash.
uint32_t current_hash_ = 0; // Running CRC hash of frame.
uint32_t given_hash_ = 0; // True CRC hash of frame.
uint32_t current_frame_number_ = 0; // Current frame for CRC hash.
uint32_t bad_frame_number_ = 0; // Frame number with bad hash.
OEMCryptoResult hash_error_ =
OEMCrypto_SUCCESS; // Error code for first bad frame.
// The bare minimum state machine is to only call each of these function
// categories at most once.
bool state_nonce_created_;
bool state_request_signed_;
bool state_response_loaded_;
bool state_nonce_created_ = false;
bool state_request_signed_ = false;
bool state_response_loaded_ = false;
CORE_DISALLOW_COPY_AND_ASSIGN(SessionContext);
};