Browse Source

Better reuse of state

Signed-off-by: crueter <crueter@eden-emu.dev>
pull/3606/head
crueter 2 weeks ago
parent
commit
18c892bb78
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 37
      src/core/crypto/aes_util.cpp
  2. 10
      src/core/crypto/key_manager.cpp
  3. 33
      src/core/file_sys/xts_archive.cpp

37
src/core/crypto/aes_util.cpp

@ -35,7 +35,7 @@ struct CipherContext {
EVP_CIPHER* cipher = nullptr;
};
inline const std::string GetCipherName(Mode mode, u32 key_size) {
static inline const std::string GetCipherName(Mode mode, u32 key_size) {
std::string cipher;
std::size_t effective_bits = key_size * 8;
@ -57,6 +57,34 @@ inline const std::string GetCipherName(Mode mode, u32 key_size) {
return fmt::format("AES-{}-{}", effective_bits, cipher);
};
static EVP_CIPHER *GetCipher(Mode mode, u32 key_size) {
static auto fetch_cipher = [](Mode m, u32 k) {
return EVP_CIPHER_fetch(nullptr, GetCipherName(m, k).c_str(), nullptr);
};
static const struct {
EVP_CIPHER* ctr_16 = fetch_cipher(Mode::CTR, 16);
EVP_CIPHER* ecb_16 = fetch_cipher(Mode::ECB, 16);
EVP_CIPHER* xts_16 = fetch_cipher(Mode::XTS, 16);
EVP_CIPHER* ctr_32 = fetch_cipher(Mode::CTR, 32);
EVP_CIPHER* ecb_32 = fetch_cipher(Mode::ECB, 32);
EVP_CIPHER* xts_32 = fetch_cipher(Mode::XTS, 32);
} ciphers = {};
switch (mode) {
case Mode::CTR:
return key_size == 16 ? ciphers.ctr_16 : ciphers.ctr_32;
case Mode::ECB:
return key_size == 16 ? ciphers.ecb_16 : ciphers.ecb_32;
case Mode::XTS:
return key_size == 16 ? ciphers.xts_16 : ciphers.xts_32;
default:
UNIMPLEMENTED();
}
return nullptr;
}
// TODO: WHY TEMPLATE???????
template <typename Key, std::size_t KeySize>
Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode)
@ -64,7 +92,12 @@ Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode)
ctx->encryption_context = EVP_CIPHER_CTX_new();
ctx->decryption_context = EVP_CIPHER_CTX_new();
ctx->cipher = EVP_CIPHER_fetch(nullptr, GetCipherName(mode, KeySize).c_str(), NULL);
ctx->cipher = GetCipher(mode, KeySize);
if (ctx->cipher) {
EVP_CIPHER_up_ref(ctx->cipher);
} else {
UNIMPLEMENTED();
}
ASSERT_MSG(ctx->encryption_context && ctx->decryption_context && ctx->cipher,
"OpenSSL cipher context failed init!");

10
src/core/crypto/key_manager.cpp

@ -942,11 +942,19 @@ void KeyManager::DeriveSDSeedLazy() {
static Key128 CalculateCMAC(const u8* source, size_t size, const Key128& key) {
Key128 out{};
EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(EVP_MAC_fetch(NULL, "cmac", NULL));
static EVP_MAC* mac = EVP_MAC_fetch(nullptr, "cmac", nullptr);
if (!mac) return out;
static EVP_MAC_CTX* ctx = EVP_MAC_CTX_new(mac);
if (!ctx) return out;
EVP_MAC_init(ctx, key.data(), key.size() * CHAR_BIT, NULL);
EVP_MAC_update(ctx, source, size);
size_t len;
EVP_MAC_final(ctx, out.data(), &len, out.size());
return out;
}

33
src/core/file_sys/xts_archive.cpp

@ -30,35 +30,24 @@ constexpr u64 NAX_HEADER_PADDING_SIZE = 0x4000;
template <typename SourceData, typename SourceKey, typename Destination>
static bool CalculateHMAC256(Destination* out, const SourceKey* key, std::size_t key_length,
const SourceData* data, std::size_t data_length) {
bool success = false;
EVP_MAC* mac = nullptr;
EVP_MAC_CTX* ctx = nullptr;
size_t out_len = 0;
mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
static EVP_MAC* mac = EVP_MAC_fetch(nullptr, "HMAC", nullptr);
if (!mac) return false;
ctx = EVP_MAC_CTX_new(mac);
if (!ctx) goto cleanup;
static EVP_MAC_CTX* ctx = EVP_MAC_CTX_new(mac);
if (!ctx) return false;
{
OSSL_PARAM params[2];
params[0] = OSSL_PARAM_construct_utf8_string("digest", (char*)"SHA256", 0);
params[1] = OSSL_PARAM_construct_end();
static OSSL_PARAM params[] = {
OSSL_PARAM_construct_utf8_string("digest", (char*)"SHA256", 0),
OSSL_PARAM_construct_end()
};
if (!EVP_MAC_init(ctx, reinterpret_cast<const unsigned char*>(key), key_length, params))
goto cleanup;
}
if (EVP_MAC_update(ctx, reinterpret_cast<const unsigned char*>(data), data_length) &&
EVP_MAC_final(ctx, reinterpret_cast<unsigned char*>(out), &out_len, 32)) {
success = true;
}
if (!EVP_MAC_init(ctx, reinterpret_cast<const unsigned char*>(key), key_length, params))
return false;
cleanup:
EVP_MAC_CTX_free(ctx);
EVP_MAC_free(mac);
return success;
return EVP_MAC_update(ctx, reinterpret_cast<const unsigned char*>(data), data_length) &&
EVP_MAC_final(ctx, reinterpret_cast<unsigned char*>(out), &out_len, 32);
}
NAX::NAX(VirtualFile file_)

Loading…
Cancel
Save