|
|
|
@ -53,24 +53,27 @@ Result NcaReader::Initialize(VirtualFile base_storage, const NcaCryptoConfigurat |
|
|
|
// Generate keys for header.
|
|
|
|
using AesXtsStorageForNcaHeader = AesXtsStorage; |
|
|
|
|
|
|
|
constexpr const s32 HeaderKeyTypeValues[NcaCryptoConfiguration::HeaderEncryptionKeyCount] = { |
|
|
|
static_cast<s32>(KeyType::NcaHeaderKey1), |
|
|
|
static_cast<s32>(KeyType::NcaHeaderKey2), |
|
|
|
}; |
|
|
|
|
|
|
|
u8 header_decryption_keys[NcaCryptoConfiguration::HeaderEncryptionKeyCount] |
|
|
|
[NcaCryptoConfiguration::Aes128KeySize]; |
|
|
|
constexpr std::array<s32, NcaCryptoConfiguration::HeaderEncryptionKeyCount> |
|
|
|
HeaderKeyTypeValues = { |
|
|
|
static_cast<s32>(KeyType::NcaHeaderKey1), |
|
|
|
static_cast<s32>(KeyType::NcaHeaderKey2), |
|
|
|
}; |
|
|
|
|
|
|
|
std::array<std::array<u8, NcaCryptoConfiguration::Aes128KeySize>, |
|
|
|
NcaCryptoConfiguration::HeaderEncryptionKeyCount> |
|
|
|
header_decryption_keys; |
|
|
|
for (size_t i = 0; i < NcaCryptoConfiguration::HeaderEncryptionKeyCount; i++) { |
|
|
|
crypto_cfg.generate_key(header_decryption_keys[i], AesXtsStorageForNcaHeader::KeySize, |
|
|
|
crypto_cfg.header_encrypted_encryption_keys[i], |
|
|
|
crypto_cfg.generate_key(header_decryption_keys[i].data(), |
|
|
|
AesXtsStorageForNcaHeader::KeySize, |
|
|
|
crypto_cfg.header_encrypted_encryption_keys[i].data(), |
|
|
|
AesXtsStorageForNcaHeader::KeySize, HeaderKeyTypeValues[i]); |
|
|
|
} |
|
|
|
|
|
|
|
// Create the header storage.
|
|
|
|
const u8 header_iv[AesXtsStorageForNcaHeader::IvSize] = {}; |
|
|
|
std::array<u8, AesXtsStorageForNcaHeader::IvSize> header_iv = {}; |
|
|
|
work_header_storage = std::make_unique<AesXtsStorageForNcaHeader>( |
|
|
|
base_storage, header_decryption_keys[0], header_decryption_keys[1], |
|
|
|
AesXtsStorageForNcaHeader::KeySize, header_iv, AesXtsStorageForNcaHeader::IvSize, |
|
|
|
base_storage, header_decryption_keys[0].data(), header_decryption_keys[1].data(), |
|
|
|
AesXtsStorageForNcaHeader::KeySize, header_iv.data(), AesXtsStorageForNcaHeader::IvSize, |
|
|
|
NcaHeader::XtsBlockSize); |
|
|
|
|
|
|
|
// Check that we successfully created the storage.
|
|
|
|
@ -94,20 +97,6 @@ Result NcaReader::Initialize(VirtualFile base_storage, const NcaCryptoConfigurat |
|
|
|
m_header_encryption_type = NcaHeader::EncryptionType::None; |
|
|
|
} |
|
|
|
|
|
|
|
// Validate the fixed key signature.
|
|
|
|
if (m_header.header1_signature_key_generation > |
|
|
|
NcaCryptoConfiguration::Header1SignatureKeyGenerationMax) { |
|
|
|
LOG_CRITICAL(Frontend, |
|
|
|
"NcaCryptoConfiguration::Header1SignatureKeyGenerationMax = {}, " |
|
|
|
"m_header.header1_signature_key_generation = {}", |
|
|
|
NcaCryptoConfiguration::Header1SignatureKeyGenerationMax, |
|
|
|
m_header.header1_signature_key_generation); |
|
|
|
} |
|
|
|
|
|
|
|
R_UNLESS(m_header.header1_signature_key_generation <= |
|
|
|
NcaCryptoConfiguration::Header1SignatureKeyGenerationMax, |
|
|
|
ResultInvalidNcaHeader1SignatureKeyGeneration); |
|
|
|
|
|
|
|
// Verify the header sign1.
|
|
|
|
if (crypto_cfg.verify_sign1 != nullptr) { |
|
|
|
const u8* sig = m_header.header_sign_1.data(); |
|
|
|
@ -138,31 +127,31 @@ Result NcaReader::Initialize(VirtualFile base_storage, const NcaCryptoConfigurat |
|
|
|
if (std::memcmp(ZeroRightsId.data(), m_header.rights_id.data(), NcaHeader::RightsIdSize) == 0) { |
|
|
|
// If we don't, then we don't have an external key, so we need to generate decryption keys.
|
|
|
|
crypto_cfg.generate_key( |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesCtr], Aes128KeySize, |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesCtr].data(), Aes128KeySize, |
|
|
|
m_header.encrypted_key_area.data() + NcaHeader::DecryptionKey_AesCtr * Aes128KeySize, |
|
|
|
Aes128KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration())); |
|
|
|
crypto_cfg.generate_key( |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesXts1], Aes128KeySize, |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesXts1].data(), Aes128KeySize, |
|
|
|
m_header.encrypted_key_area.data() + NcaHeader::DecryptionKey_AesXts1 * Aes128KeySize, |
|
|
|
Aes128KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration())); |
|
|
|
crypto_cfg.generate_key( |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesXts2], Aes128KeySize, |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesXts2].data(), Aes128KeySize, |
|
|
|
m_header.encrypted_key_area.data() + NcaHeader::DecryptionKey_AesXts2 * Aes128KeySize, |
|
|
|
Aes128KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration())); |
|
|
|
crypto_cfg.generate_key( |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesCtrEx], Aes128KeySize, |
|
|
|
m_decryption_keys[NcaHeader::DecryptionKey_AesCtrEx].data(), Aes128KeySize, |
|
|
|
m_header.encrypted_key_area.data() + NcaHeader::DecryptionKey_AesCtrEx * Aes128KeySize, |
|
|
|
Aes128KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration())); |
|
|
|
|
|
|
|
// Copy the hardware speed emulation key.
|
|
|
|
std::memcpy(m_decryption_keys[NcaHeader::DecryptionKey_AesCtrHw], |
|
|
|
std::memcpy(m_decryption_keys[NcaHeader::DecryptionKey_AesCtrHw].data(), |
|
|
|
m_header.encrypted_key_area.data() + |
|
|
|
NcaHeader::DecryptionKey_AesCtrHw * Aes128KeySize, |
|
|
|
Aes128KeySize); |
|
|
|
} |
|
|
|
|
|
|
|
// Clear the external decryption key.
|
|
|
|
std::memset(m_external_decryption_key, 0, sizeof(m_external_decryption_key)); |
|
|
|
std::memset(m_external_decryption_key.data(), 0, m_external_decryption_key.size()); |
|
|
|
|
|
|
|
// Set software key availability.
|
|
|
|
m_is_available_sw_key = crypto_cfg.is_available_sw_key; |
|
|
|
@ -304,7 +293,7 @@ void NcaReader::GetEncryptedKey(void* dst, size_t size) const { |
|
|
|
const void* NcaReader::GetDecryptionKey(s32 index) const { |
|
|
|
ASSERT(m_body_storage != nullptr); |
|
|
|
ASSERT(0 <= index && index < NcaHeader::DecryptionKey_Count); |
|
|
|
return m_decryption_keys[index]; |
|
|
|
return m_decryption_keys[index].data(); |
|
|
|
} |
|
|
|
|
|
|
|
bool NcaReader::HasValidInternalKey() const { |
|
|
|
@ -339,14 +328,14 @@ bool NcaReader::HasExternalDecryptionKey() const { |
|
|
|
} |
|
|
|
|
|
|
|
const void* NcaReader::GetExternalDecryptionKey() const { |
|
|
|
return m_external_decryption_key; |
|
|
|
return m_external_decryption_key.data(); |
|
|
|
} |
|
|
|
|
|
|
|
void NcaReader::SetExternalDecryptionKey(const void* src, size_t size) { |
|
|
|
ASSERT(src != nullptr); |
|
|
|
ASSERT(size == sizeof(m_external_decryption_key)); |
|
|
|
|
|
|
|
std::memcpy(m_external_decryption_key, src, sizeof(m_external_decryption_key)); |
|
|
|
std::memcpy(m_external_decryption_key.data(), src, sizeof(m_external_decryption_key)); |
|
|
|
} |
|
|
|
|
|
|
|
void NcaReader::GetRawData(void* dst, size_t dst_size) const { |
|
|
|
|