diff options
| author | lizzie <lizzie@eden-emu.dev> | 2025-10-17 05:08:51 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-10-17 05:08:51 +0200 |
| commit | 440ee4916dd618cea27040fdb9e1c185ac3494f8 (patch) | |
| tree | 9e2f6738367355f8f1169098b3ace81721a53580 /src/core/crypto/aes_util.cpp | |
| parent | 551f244dfd48d0e0c1d6db82b39d1ccaa1b6dc06 (diff) | |
[nca] Use better tight loop allocation schemes (none at all) for AES decrypt/encrypt and force MbedTLS to use AES x86_64 instructions (#2750)
Uses stack instead of allocating stuff haphazardly (16 bytes and 512 bytes respectively) - removes malloc() pollution and all that nasty stuff from tight loops
Original work by Ribbit but edited by me.
Will NOT bring a massive speedup since the main bottleneck is mbedtls itself, but may bring nice oddities to STARTUP TIMES nonetheless.
AES instructions being forced wont affect CPUs without them since there is always a runtime check for them.
Signed-off-by: lizzie lizzie@eden-emu.dev
Co-authored-by: Ribbit <ribbit@placeholder.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2750
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src/core/crypto/aes_util.cpp')
| -rw-r--r-- | src/core/crypto/aes_util.cpp | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp index cd7e15a582..5c31eff3e1 100644 --- a/src/core/crypto/aes_util.cpp +++ b/src/core/crypto/aes_util.cpp @@ -1,7 +1,11 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include <array> +#include <vector> #include <mbedtls/cipher.h> #include "common/assert.h" #include "common/logging/log.h" @@ -71,37 +75,37 @@ void AESCipher<Key, KeySize>::Transcode(const u8* src, std::size_t size, u8* des mbedtls_cipher_reset(context); + // Only ECB strictly requires block sized chunks. std::size_t written = 0; - if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { + if (mbedtls_cipher_get_cipher_mode(context) != MBEDTLS_MODE_ECB) { mbedtls_cipher_update(context, src, size, dest, &written); - if (written != size) { - LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", - size, written); - } - } else { - const auto block_size = mbedtls_cipher_get_block_size(context); - if (size < block_size) { - std::vector<u8> block(block_size); - std::memcpy(block.data(), src, size); - Transcode(block.data(), block.size(), block.data(), op); - std::memcpy(dest, block.data(), size); - return; - } + if (written != size) + LOG_WARNING(Crypto, "Not all data was processed requested={:016X}, actual={:016X}.", size, written); + return; + } + + // ECB path: operate in block sized chunks and mirror previous behavior. + const auto block_size = mbedtls_cipher_get_block_size(context); + if (size < block_size) { + std::vector<u8> block(block_size); + std::memcpy(block.data(), src, size); + Transcode(block.data(), block.size(), block.data(), op); + std::memcpy(dest, block.data(), size); + return; + } - for (std::size_t offset = 0; offset < size; offset += block_size) { - auto length = std::min<std::size_t>(block_size, size - offset); - mbedtls_cipher_update(context, src + offset, length, dest + offset, &written); - if (written != length) { - if (length < block_size) { - std::vector<u8> block(block_size); - std::memcpy(block.data(), src + offset, length); - Transcode(block.data(), block.size(), block.data(), op); - std::memcpy(dest + offset, block.data(), length); - return; - } - LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", - length, written); + for (std::size_t offset = 0; offset < size; offset += block_size) { + const auto length = std::min<std::size_t>(block_size, size - offset); + mbedtls_cipher_update(context, src + offset, length, dest + offset, &written); + if (written != length) { + if (length < block_size) { + std::vector<u8> block(block_size); + std::memcpy(block.data(), src + offset, length); + Transcode(block.data(), block.size(), block.data(), op); + std::memcpy(dest + offset, block.data(), length); + return; } + LOG_WARNING(Crypto, "Not all data was processed requested={:016X}, actual={:016X}.", length, written); } } } |
