mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-09 21:51:45 +00:00
exo2: fix bugs in device unique data decrypytion
This commit is contained in:
parent
b922dff414
commit
1e0124fb67
2 changed files with 24 additions and 9 deletions
|
@ -26,8 +26,8 @@ namespace ams::secmon::smc {
|
|||
constexpr inline size_t DeviceUniqueDataDeviceIdSize = sizeof(u64);
|
||||
constexpr inline size_t DeviceUniqueDataPaddingSize = se::AesBlockSize - DeviceUniqueDataDeviceIdSize;
|
||||
|
||||
constexpr inline size_t DeviceUniqueDataOuterMetaSize = DeviceUniqueDataIvSize;
|
||||
constexpr inline size_t DeviceUniqueDataInnerMetaSize = DeviceUniqueDataMacSize + DeviceUniqueDataDeviceIdSize + DeviceUniqueDataPaddingSize;
|
||||
constexpr inline size_t DeviceUniqueDataOuterMetaSize = DeviceUniqueDataIvSize + DeviceUniqueDataMacSize;
|
||||
constexpr inline size_t DeviceUniqueDataInnerMetaSize = DeviceUniqueDataPaddingSize + DeviceUniqueDataDeviceIdSize;
|
||||
constexpr inline size_t DeviceUniqueDataTotalMetaSize = DeviceUniqueDataOuterMetaSize + DeviceUniqueDataInnerMetaSize;
|
||||
|
||||
void PrepareDeviceUniqueDataKey(const void *seal_key_source, size_t seal_key_source_size, const void *access_key, size_t access_key_size, const void *key_source, size_t key_source_size) {
|
||||
|
@ -41,6 +41,21 @@ namespace ams::secmon::smc {
|
|||
se::SetEncryptedAesKey128(pkg1::AesKeySlot_Smc, pkg1::AesKeySlot_Smc, key_source, key_source_size);
|
||||
}
|
||||
|
||||
void ComputeAes128Ctr(void *dst, size_t dst_size, int slot, const void *src, size_t src_size, const void *iv, size_t iv_size) {
|
||||
/* Ensure that the SE sees consistent data. */
|
||||
hw::FlushDataCache(src, src_size);
|
||||
hw::FlushDataCache(dst, dst_size);
|
||||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
|
||||
/* Use the security engine to transform the data. */
|
||||
se::ComputeAes128Ctr(dst, dst_size, slot, src, src_size, iv, iv_size);
|
||||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
|
||||
/* Ensure the CPU sees consistent data. */
|
||||
hw::FlushDataCache(dst, dst_size);
|
||||
hw::DataSynchronizationBarrierInnerShareable();
|
||||
}
|
||||
|
||||
void ComputeGmac(void *dst, size_t dst_size, const void *data, size_t data_size, const void *iv, size_t iv_size) {
|
||||
/* Declare keyslot (as encryptor will need to take it by pointer/reference). */
|
||||
constexpr int Slot = pkg1::AesKeySlot_Smc;
|
||||
|
@ -68,8 +83,8 @@ namespace ams::secmon::smc {
|
|||
|
||||
bool DecryptDeviceUniqueData(void *dst, size_t dst_size, u8 *out_device_id_high, const void *seal_key_source, size_t seal_key_source_size, const void *access_key, size_t access_key_size, const void *key_source, size_t key_source_size, const void *src, size_t src_size) {
|
||||
/* Determine how much decrypted data there will be. */
|
||||
const size_t enc_size = src_size - DeviceUniqueDataInnerMetaSize;
|
||||
const size_t dec_size = src_size - DeviceUniqueDataOuterMetaSize;
|
||||
const size_t enc_size = src_size - DeviceUniqueDataOuterMetaSize;
|
||||
const size_t dec_size = enc_size - DeviceUniqueDataInnerMetaSize;
|
||||
|
||||
/* Ensure that our sizes are allowed. */
|
||||
AMS_ABORT_UNLESS(src_size > DeviceUniqueDataTotalMetaSize);
|
||||
|
@ -94,7 +109,7 @@ namespace ams::secmon::smc {
|
|||
std::memcpy(temp_iv, iv, sizeof(temp_iv));
|
||||
|
||||
/* Decrypt the data. */
|
||||
se::ComputeAes128Ctr(dst, dst_size, pkg1::AesKeySlot_Smc, enc, enc_size, temp_iv, DeviceUniqueDataIvSize);
|
||||
ComputeAes128Ctr(dst, dst_size, pkg1::AesKeySlot_Smc, enc, enc_size, temp_iv, DeviceUniqueDataIvSize);
|
||||
|
||||
/* Compute the gmac. */
|
||||
ComputeGmac(calc_mac, DeviceUniqueDataMacSize, dst, enc_size, temp_iv, DeviceUniqueDataIvSize);
|
||||
|
|
|
@ -188,7 +188,7 @@ namespace ams::crypto::impl {
|
|||
if (this->aad_remaining > 0) {
|
||||
while (aad_size > 0) {
|
||||
/* Copy in a byte of the aad to our partial block. */
|
||||
this->block_x.block_8[BlockSize - 1 - this->aad_remaining] ^= *(cur_aad++);
|
||||
this->block_x.block_8[this->aad_remaining] ^= *(cur_aad++);
|
||||
|
||||
/* Note that we consumed a byte. */
|
||||
--aad_size;
|
||||
|
@ -205,7 +205,7 @@ namespace ams::crypto::impl {
|
|||
while (aad_size >= BlockSize) {
|
||||
/* Xor the current aad into our work block. */
|
||||
for (size_t i = 0; i < BlockSize; ++i) {
|
||||
this->block_x.block_8[BlockSize - 1 - i] ^= *(cur_aad++);
|
||||
this->block_x.block_8[i] ^= *(cur_aad++);
|
||||
}
|
||||
|
||||
/* Multiply the blocks in our galois field. */
|
||||
|
@ -222,7 +222,7 @@ namespace ams::crypto::impl {
|
|||
|
||||
/* Xor the data in. */
|
||||
for (size_t i = 0; i < aad_size; ++i) {
|
||||
this->block_x.block_8[BlockSize - 1 - i] ^= *(cur_aad++);
|
||||
this->block_x.block_8[i] ^= *(cur_aad++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ namespace ams::crypto::impl {
|
|||
GaloisFieldMult(std::addressof(this->block_x), std::addressof(this->block_x), std::addressof(this->h_mult_blocks[0]));
|
||||
|
||||
/* If we need to do an encryption, do so. */
|
||||
{
|
||||
if (encrypt) {
|
||||
/* Encrypt the iv. */
|
||||
u8 enc_result[BlockSize];
|
||||
this->ProcessBlock(enc_result, std::addressof(this->block_ek0), this->block_cipher);
|
||||
|
|
Loading…
Reference in a new issue