Browse Source

convert NCA loader

Signed-off-by: crueter <crueter@eden-emu.dev>
pull/3606/head
crueter 2 weeks ago
parent
commit
04117ad155
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 26
      src/core/loader/nca.cpp

26
src/core/loader/nca.cpp

@ -5,6 +5,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <utility> #include <utility>
#include <openssl/err.h>
#include <openssl/evp.h>
#include "common/hex_util.h" #include "common/hex_util.h"
#include "common/scope_exit.h" #include "common/scope_exit.h"
@ -17,7 +19,6 @@
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/deconstructed_rom_directory.h" #include "core/loader/deconstructed_rom_directory.h"
#include "core/loader/nca.h" #include "core/loader/nca.h"
#include "mbedtls/sha256.h"
#include "common/literals.h" #include "common/literals.h"
namespace Loader { namespace Loader {
@ -133,9 +134,8 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)>
const auto name = file->GetName(); const auto name = file->GetName();
// We won't try to verify meta NCAs. // We won't try to verify meta NCAs.
if (name.ends_with(".cnmt.nca")) {
if (name.ends_with(".cnmt.nca"))
return ResultStatus::Success; return ResultStatus::Success;
}
// Check if we can verify this file. NCAs should be named after their hashes. // Check if we can verify this file. NCAs should be named after their hashes.
if (!name.ends_with(".nca") || name.size() != NcaFileNameWithHashLength) { if (!name.ends_with(".nca") || name.size() != NcaFileNameWithHashLength) {
@ -151,15 +151,18 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)>
std::vector<u8> buffer(4_MiB); std::vector<u8> buffer(4_MiB);
// Initialize sha256 verification context. // Initialize sha256 verification context.
mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
mbedtls_sha256_starts(&ctx, 0);
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
if (!ctx)
return ResultStatus::ErrorNotInitialized;
// Ensure we maintain a clean state on exit. // Ensure we maintain a clean state on exit.
SCOPE_EXIT { SCOPE_EXIT {
mbedtls_sha256_free(&ctx);
EVP_MD_CTX_free(ctx);
}; };
if (!EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr))
return ResultStatus::ErrorIntegrityVerificationFailed;
// Declare counters. // Declare counters.
const size_t total_size = file->GetSize(); const size_t total_size = file->GetSize();
size_t processed_size = 0; size_t processed_size = 0;
@ -171,7 +174,9 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)>
const size_t read_size = file->Read(buffer.data(), intended_read_size, processed_size); const size_t read_size = file->Read(buffer.data(), intended_read_size, processed_size);
// Update the hash function with the buffer contents. // Update the hash function with the buffer contents.
mbedtls_sha256_update(&ctx, buffer.data(), read_size);
if (!EVP_DigestUpdate(ctx, buffer.data(), read_size)) {
return ResultStatus::ErrorIntegrityVerificationFailed;
}
// Update counters. // Update counters.
processed_size += read_size; processed_size += read_size;
@ -184,7 +189,10 @@ ResultStatus AppLoader_NCA::VerifyIntegrity(std::function<bool(size_t, size_t)>
// Finalize context and compute the output hash. // Finalize context and compute the output hash.
std::array<u8, NcaSha256HashLength> output_hash; std::array<u8, NcaSha256HashLength> output_hash;
mbedtls_sha256_finish(&ctx, output_hash.data());
unsigned int output_len = 0;
if (!EVP_DigestFinal_ex(ctx, output_hash.data(), &output_len)) {
return ResultStatus::ErrorIntegrityVerificationFailed;
}
// Compare to expected. // Compare to expected.
if (std::memcmp(input_hash.data(), output_hash.data(), NcaSha256HalfHashLength) != 0) { if (std::memcmp(input_hash.data(), output_hash.data(), NcaSha256HalfHashLength) != 0) {

Loading…
Cancel
Save