diff --git a/exosphere2/program/source/smc/secmon_smc_device_unique_data.cpp b/exosphere2/program/source/smc/secmon_smc_device_unique_data.cpp index df4a227d4..e14dfbe18 100644 --- a/exosphere2/program/source/smc/secmon_smc_device_unique_data.cpp +++ b/exosphere2/program/source/smc/secmon_smc_device_unique_data.cpp @@ -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); diff --git a/libraries/libvapours/source/crypto/impl/crypto_gcm_mode_impl.arch.arm64.cpp b/libraries/libvapours/source/crypto/impl/crypto_gcm_mode_impl.arch.arm64.cpp index 1b7c2995c..9b6ba6c4b 100644 --- a/libraries/libvapours/source/crypto/impl/crypto_gcm_mode_impl.arch.arm64.cpp +++ b/libraries/libvapours/source/crypto/impl/crypto_gcm_mode_impl.arch.arm64.cpp @@ -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);