From 1e7f41ea9fc85d0a9f93f64acc2a82f8bf1bd41a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 22 Jun 2019 12:30:36 -0700 Subject: [PATCH] boot: move updater into libstrat --- stratosphere/boot/Makefile | 2 +- .../boot/source/boot_repair_boot_images.cpp | 3 +- .../boot/source/updater/updater_api.cpp | 562 ------------------ .../boot/source/updater/updater_api.hpp | 30 - .../source/updater/updater_bis_management.cpp | 168 ------ .../source/updater/updater_bis_management.hpp | 239 -------- .../boot/source/updater/updater_bis_save.cpp | 66 -- .../boot/source/updater/updater_bis_save.hpp | 46 -- .../boot/source/updater/updater_files.cpp | 72 --- .../boot/source/updater/updater_files.hpp | 29 - .../boot/source/updater/updater_paths.cpp | 119 ---- .../boot/source/updater/updater_paths.hpp | 31 - .../boot/source/updater/updater_types.hpp | 45 -- stratosphere/libstratosphere | 2 +- 14 files changed, 3 insertions(+), 1411 deletions(-) delete mode 100644 stratosphere/boot/source/updater/updater_api.cpp delete mode 100644 stratosphere/boot/source/updater/updater_api.hpp delete mode 100644 stratosphere/boot/source/updater/updater_bis_management.cpp delete mode 100644 stratosphere/boot/source/updater/updater_bis_management.hpp delete mode 100644 stratosphere/boot/source/updater/updater_bis_save.cpp delete mode 100644 stratosphere/boot/source/updater/updater_bis_save.hpp delete mode 100644 stratosphere/boot/source/updater/updater_files.cpp delete mode 100644 stratosphere/boot/source/updater/updater_files.hpp delete mode 100644 stratosphere/boot/source/updater/updater_paths.cpp delete mode 100644 stratosphere/boot/source/updater/updater_paths.hpp delete mode 100644 stratosphere/boot/source/updater/updater_types.hpp diff --git a/stratosphere/boot/Makefile b/stratosphere/boot/Makefile index 8574f6933..8714afa85 100644 --- a/stratosphere/boot/Makefile +++ b/stratosphere/boot/Makefile @@ -33,7 +33,7 @@ endef #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) BUILD := build -SOURCES := source source/i2c source/i2c/driver source/i2c/driver/impl source/updater source/gpio source/pinmux +SOURCES := source source/i2c source/i2c/driver source/i2c/driver/impl source/gpio source/pinmux DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src diff --git a/stratosphere/boot/source/boot_repair_boot_images.cpp b/stratosphere/boot/source/boot_repair_boot_images.cpp index e2ae290b7..2475d2ace 100644 --- a/stratosphere/boot/source/boot_repair_boot_images.cpp +++ b/stratosphere/boot/source/boot_repair_boot_images.cpp @@ -15,12 +15,11 @@ */ #include +#include #include "boot_power_utils.hpp" #include "boot_repair_boot_images.hpp" -#include "updater/updater_api.hpp" - namespace sts::boot { namespace { diff --git a/stratosphere/boot/source/updater/updater_api.cpp b/stratosphere/boot/source/updater/updater_api.cpp deleted file mode 100644 index ad80303d2..000000000 --- a/stratosphere/boot/source/updater/updater_api.cpp +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "updater_api.hpp" -#include "updater_bis_save.hpp" -#include "updater_files.hpp" -#include "updater_paths.hpp" - -namespace sts::updater { - - namespace { - - /* Validation Prototypes. */ - Result ValidateWorkBuffer(const void *work_buffer, size_t work_buffer_size); - - /* Configuration Prototypes. */ - bool HasEks(BootImageUpdateType boot_image_update_type); - bool HasAutoRcmPreserve(BootImageUpdateType boot_image_update_type); - u32 GetNcmTitleType(BootModeType mode); - Result GetBootImagePackageDataId(u64 *out_data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size); - - /* Verification Prototypes. */ - Result GetVerificationState(VerificationState *out, void *work_buffer, size_t work_buffer_size); - Result VerifyBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result VerifyBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result VerifyBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - - /* Update Prototypes. */ - Result SetVerificationNeeded(BootModeType mode, bool needed, void *work_buffer, size_t work_buffer_size); - Result UpdateBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result UpdateBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result UpdateBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - - /* Package helpers. */ - Result ValidateBctFileHash(Boot0Accessor &accessor, Boot0Partition which, const void *stored_hash, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result GetPackage2Hash(void *dst_hash, size_t package2_size, void *work_buffer, size_t work_buffer_size, Package2Type which); - Result WritePackage2(void *work_buffer, size_t work_buffer_size, Package2Type which, BootImageUpdateType boot_image_update_type); - - /* Implementations. */ - Result ValidateWorkBuffer(const void *work_buffer, size_t work_buffer_size) { - if (work_buffer_size < BctSize + EksSize) { - return ResultUpdaterTooSmallWorkBuffer; - } - if (reinterpret_cast(work_buffer) & 0xFFF) { - return ResultUpdaterMisalignedWorkBuffer; - } - if (reinterpret_cast(work_buffer_size) & 0x1FF) { - return ResultUpdaterMisalignedWorkBuffer; - } - return ResultSuccess; - } - - bool HasEks(BootImageUpdateType boot_image_update_type) { - switch (boot_image_update_type) { - case BootImageUpdateType::Erista: - return true; - case BootImageUpdateType::Mariko: - return false; - default: - std::abort(); - } - } - - bool HasAutoRcmPreserve(BootImageUpdateType boot_image_update_type) { - switch (boot_image_update_type) { - case BootImageUpdateType::Erista: - return true; - case BootImageUpdateType::Mariko: - return false; - default: - std::abort(); - } - } - - u32 GetNcmTitleType(BootModeType mode) { - switch (mode) { - case BootModeType::Normal: - return NcmContentMetaType_BootImagePackage; - case BootModeType::Safe: - return NcmContentMetaType_BootImagePackageSafe; - default: - std::abort(); - } - } - - Result GetVerificationState(VerificationState *out, void *work_buffer, size_t work_buffer_size) { - /* Always set output to true before doing anything else. */ - out->needs_verify_normal = true; - out->needs_verify_safe = true; - - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - /* Initialize boot0 save accessor. */ - BisSave save; - R_TRY(save.Initialize(work_buffer, work_buffer_size)); - ON_SCOPE_EXIT { save.Finalize(); }; - - /* Load save from NAND. */ - R_TRY(save.Load()); - - /* Read data from save. */ - out->needs_verify_normal = save.GetNeedsVerification(BootModeType::Normal); - out->needs_verify_safe = save.GetNeedsVerification(BootModeType::Safe); - return ResultSuccess; - } - - Result VerifyBootImagesAndRepairIfNeeded(bool *out_repaired, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - /* Get system data id for boot images (819/81A/81B/81C). */ - u64 bip_data_id = 0; - R_TRY(GetBootImagePackageDataId(&bip_data_id, mode, work_buffer, work_buffer_size)); - - /* Verify the boot images in NAND. */ - R_TRY_CATCH(VerifyBootImages(bip_data_id, mode, work_buffer, work_buffer_size, boot_image_update_type)) { - R_CATCH(ResultUpdaterNeedsRepairBootImages) { - /* Perform repair. */ - *out_repaired = true; - R_TRY(UpdateBootImages(bip_data_id, mode, work_buffer, work_buffer_size, boot_image_update_type)); - } - } R_END_TRY_CATCH; - - /* We've either just verified or just repaired. Either way, we don't need to verify any more. */ - return SetVerificationNeeded(mode, false, work_buffer, work_buffer_size); - } - - Result GetBootImagePackageDataId(u64 *out_data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size) { - /* Ensure we can read content metas. */ - constexpr size_t MaxContentMetas = 0x40; - if (work_buffer_size < sizeof(NcmMetaRecord) * MaxContentMetas) { - std::abort(); - } - - /* Open NAND System meta database, list contents. */ - NcmContentMetaDatabase meta_db; - R_TRY(ncmOpenContentMetaDatabase(FsStorageId_NandSystem, &meta_db)); - ON_SCOPE_EXIT { serviceClose(&meta_db.s); }; - - NcmMetaRecord *records = reinterpret_cast(work_buffer); - - const u32 title_type = GetNcmTitleType(mode); - u32 written_entries; - u32 total_entries; - R_TRY(ncmContentMetaDatabaseList(&meta_db, title_type, 0, 0, UINT64_MAX, records, MaxContentMetas * sizeof(*records), &written_entries, &total_entries)); - if (total_entries == 0) { - return ResultUpdaterBootImagePackageNotFound; - } - - if (total_entries != written_entries) { - std::abort(); - } - - /* Output is sorted, return the lowest valid exfat entry. */ - if (total_entries > 1) { - for (size_t i = 0; i < total_entries; i++) { - u8 attr; - R_TRY(ncmContentMetaDatabaseGetAttributes(&meta_db, &records[i], &attr)); - - if (attr & NcmContentMetaAttribute_Exfat) { - *out_data_id = records[i].titleId; - return ResultSuccess; - } - } - } - - /* If there's only one entry or no exfat entries, return that entry. */ - *out_data_id = records[0].titleId; - return ResultSuccess; - } - - Result VerifyBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - switch (mode) { - case BootModeType::Normal: - return VerifyBootImagesNormal(data_id, work_buffer, work_buffer_size, boot_image_update_type); - case BootModeType::Safe: - return VerifyBootImagesSafe(data_id, work_buffer, work_buffer_size, boot_image_update_type); - default: - std::abort(); - } - } - - Result VerifyBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } - } R_END_TRY_CATCH; - ON_SCOPE_EXIT { if (R_FAILED(romfsUnmount(GetBootImagePackageMountPath()))) { std::abort(); } }; - - /* Read and validate hashes of boot images. */ - { - size_t size; - u8 nand_hash[SHA256_HASH_SIZE]; - u8 file_hash[SHA256_HASH_SIZE]; - - Boot0Accessor boot0_accessor; - R_TRY(boot0_accessor.Initialize()); - ON_SCOPE_EXIT { boot0_accessor.Finalize(); }; - - /* Compare BCT hashes. */ - R_TRY(boot0_accessor.GetHash(nand_hash, BctSize, work_buffer, work_buffer_size, Boot0Partition::BctNormalMain)); - R_TRY(ValidateBctFileHash(boot0_accessor, Boot0Partition::BctNormalMain, nand_hash, work_buffer, work_buffer_size, boot_image_update_type)); - - /* Compare BCT Sub hashes. */ - R_TRY(boot0_accessor.GetHash(nand_hash, BctSize, work_buffer, work_buffer_size, Boot0Partition::BctNormalSub)); - R_TRY(ValidateBctFileHash(boot0_accessor, Boot0Partition::BctNormalSub, nand_hash, work_buffer, work_buffer_size, boot_image_update_type)); - - /* Compare Package1 Normal/Sub hashes. */ - R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size)); - R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - - /* Compare Package2 Normal/Sub hashes. */ - R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size)); - R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - } - - return ResultSuccess; - } - - Result VerifyBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } - } R_END_TRY_CATCH; - ON_SCOPE_EXIT { if (R_FAILED(romfsUnmount(GetBootImagePackageMountPath()))) { std::abort(); } }; - - /* Read and validate hashes of boot images. */ - { - size_t size; - u8 nand_hash[SHA256_HASH_SIZE]; - u8 file_hash[SHA256_HASH_SIZE]; - - Boot0Accessor boot0_accessor; - R_TRY(boot0_accessor.Initialize()); - ON_SCOPE_EXIT { boot0_accessor.Finalize(); }; - - Boot1Accessor boot1_accessor; - R_TRY(boot1_accessor.Initialize()); - ON_SCOPE_EXIT { boot1_accessor.Finalize(); }; - - - /* Compare BCT hashes. */ - R_TRY(boot0_accessor.GetHash(nand_hash, BctSize, work_buffer, work_buffer_size, Boot0Partition::BctSafeMain)); - R_TRY(ValidateBctFileHash(boot0_accessor, Boot0Partition::BctSafeMain, nand_hash, work_buffer, work_buffer_size, boot_image_update_type)); - - /* Compare BCT Sub hashes. */ - R_TRY(boot0_accessor.GetHash(nand_hash, BctSize, work_buffer, work_buffer_size, Boot0Partition::BctSafeSub)); - R_TRY(ValidateBctFileHash(boot0_accessor, Boot0Partition::BctSafeSub, nand_hash, work_buffer, work_buffer_size, boot_image_update_type)); - - /* Compare Package1 Normal/Sub hashes. */ - R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size)); - R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - - /* Compare Package2 Normal/Sub hashes. */ - R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size)); - R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - } - - return ResultSuccess; - } - - Result UpdateBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - switch (mode) { - case BootModeType::Normal: - return UpdateBootImagesNormal(data_id, work_buffer, work_buffer_size, boot_image_update_type); - case BootModeType::Safe: - return UpdateBootImagesSafe(data_id, work_buffer, work_buffer_size, boot_image_update_type); - default: - std::abort(); - } - } - - Result UpdateBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } - } R_END_TRY_CATCH; - ON_SCOPE_EXIT { if (R_FAILED(romfsUnmount(GetBootImagePackageMountPath()))) { std::abort(); } }; - - { - Boot0Accessor boot0_accessor; - R_TRY(boot0_accessor.Initialize()); - ON_SCOPE_EXIT { boot0_accessor.Finalize(); }; - - /* Write Package1 sub. */ - R_TRY(boot0_accessor.Clear(work_buffer, work_buffer_size, Boot0Partition::Package1NormalSub)); - R_TRY(boot0_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot0Partition::Package1NormalSub)); - - /* Write Package2 sub. */ - R_TRY(WritePackage2(work_buffer, work_buffer_size, Package2Type::NormalSub, boot_image_update_type)); - - /* Write BCT sub + BCT main, in that order. */ - { - void *bct = reinterpret_cast(reinterpret_cast(work_buffer) + 0); - void *work = reinterpret_cast(reinterpret_cast(work_buffer) + BctSize); - - size_t size; - R_TRY(ReadFile(&size, bct, BctSize, GetBctPath(boot_image_update_type))); - if (HasEks(boot_image_update_type)) { - R_TRY(boot0_accessor.UpdateEks(bct, work)); - } - - /* Only preserve autorcm if on a unit with unpatched rcm bug. */ - if (HasAutoRcmPreserve(boot_image_update_type) && !IsRcmBugPatched()) { - R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctNormalSub)); - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctNormalSub)); - R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctNormalMain)); - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctNormalMain)); - } else { - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctNormalSub)); - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctNormalMain)); - } - } - - /* Write Package2 main. */ - R_TRY(WritePackage2(work_buffer, work_buffer_size, Package2Type::NormalMain, boot_image_update_type)); - - /* Write Package1 main. */ - R_TRY(boot0_accessor.Clear(work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain)); - R_TRY(boot0_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain)); - } - - return ResultSuccess; - } - - Result UpdateBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - R_TRY_CATCH(romfsMountFromDataArchive(data_id, FsStorageId_NandSystem, GetBootImagePackageMountPath())) { - R_CATCH(ResultFsTargetNotFound) { - return ResultUpdaterBootImagePackageNotFound; - } - } R_END_TRY_CATCH; - ON_SCOPE_EXIT { if (R_FAILED(romfsUnmount(GetBootImagePackageMountPath()))) { std::abort(); } }; - - { - Boot0Accessor boot0_accessor; - R_TRY(boot0_accessor.Initialize()); - ON_SCOPE_EXIT { boot0_accessor.Finalize(); }; - - Boot1Accessor boot1_accessor; - R_TRY(boot1_accessor.Initialize()); - ON_SCOPE_EXIT { boot1_accessor.Finalize(); }; - - - /* Write Package1 sub. */ - R_TRY(boot1_accessor.Clear(work_buffer, work_buffer_size, Boot1Partition::Package1SafeSub)); - R_TRY(boot1_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot1Partition::Package1SafeSub)); - - /* Write Package2 sub. */ - R_TRY(WritePackage2(work_buffer, work_buffer_size, Package2Type::SafeSub, boot_image_update_type)); - - /* Write BCT sub + BCT main, in that order. */ - { - void *bct = reinterpret_cast(reinterpret_cast(work_buffer) + 0); - void *work = reinterpret_cast(reinterpret_cast(work_buffer) + BctSize); - - size_t size; - R_TRY(ReadFile(&size, bct, BctSize, GetBctPath(boot_image_update_type))); - if (HasEks(boot_image_update_type)) { - R_TRY(boot0_accessor.UpdateEks(bct, work)); - } - /* Only preserve autorcm if on a unit with unpatched rcm bug. */ - if (HasAutoRcmPreserve(boot_image_update_type) && !IsRcmBugPatched()) { - R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctSafeSub)); - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctSafeSub)); - R_TRY(boot0_accessor.PreserveAutoRcm(bct, work, Boot0Partition::BctSafeMain)); - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctSafeMain)); - } else { - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctSafeSub)); - R_TRY(boot0_accessor.Write(bct, BctSize, Boot0Partition::BctSafeMain)); - } - } - - /* Write Package2 main. */ - R_TRY(WritePackage2(work_buffer, work_buffer_size, Package2Type::SafeMain, boot_image_update_type)); - - /* Write Package1 main. */ - R_TRY(boot1_accessor.Clear(work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain)); - R_TRY(boot1_accessor.Write(GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain)); - } - - return ResultSuccess; - } - - Result SetVerificationNeeded(BootModeType mode, bool needed, void *work_buffer, size_t work_buffer_size) { - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - /* Initialize boot0 save accessor. */ - BisSave save; - R_TRY(save.Initialize(work_buffer, work_buffer_size)); - ON_SCOPE_EXIT { save.Finalize(); }; - - /* Load save from NAND. */ - R_TRY(save.Load()); - - /* Set whether we need to verify, then save to nand. */ - save.SetNeedsVerification(mode, needed); - R_TRY(save.Save()); - - return ResultSuccess; - } - - Result ValidateBctFileHash(Boot0Accessor &accessor, Boot0Partition which, const void *stored_hash, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - void *bct = reinterpret_cast(reinterpret_cast(work_buffer) + 0); - void *work = reinterpret_cast(reinterpret_cast(work_buffer) + BctSize); - - size_t size; - R_TRY(ReadFile(&size, bct, BctSize, GetBctPath(boot_image_update_type))); - if (HasEks(boot_image_update_type)) { - R_TRY(accessor.UpdateEks(bct, work)); - } - if (HasAutoRcmPreserve(boot_image_update_type)) { - R_TRY(accessor.PreserveAutoRcm(bct, work, which)); - } - - u8 file_hash[SHA256_HASH_SIZE]; - sha256CalculateHash(file_hash, bct, BctSize); - - if (std::memcmp(file_hash, stored_hash, SHA256_HASH_SIZE) != 0) { - return ResultUpdaterNeedsRepairBootImages; - } - - return ResultSuccess; - } - - Result GetPackage2Hash(void *dst_hash, size_t package2_size, void *work_buffer, size_t work_buffer_size, Package2Type which) { - Package2Accessor accessor(which); - R_TRY(accessor.Initialize()); - ON_SCOPE_EXIT { accessor.Finalize(); }; - - return accessor.GetHash(dst_hash, package2_size, work_buffer, work_buffer_size, Package2Partition::Package2); - } - - Result WritePackage2(void *work_buffer, size_t work_buffer_size, Package2Type which, BootImageUpdateType boot_image_update_type) { - Package2Accessor accessor(which); - R_TRY(accessor.Initialize()); - ON_SCOPE_EXIT { accessor.Finalize(); }; - - return accessor.Write(GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size, Package2Partition::Package2); - } - - } - - BootImageUpdateType GetBootImageUpdateType(spl::HardwareType hw_type) { - switch (hw_type) { - case spl::HardwareType::Icosa: - case spl::HardwareType::Copper: - return BootImageUpdateType::Erista; - case spl::HardwareType::Hoag: - case spl::HardwareType::Iowa: - return BootImageUpdateType::Mariko; - default: - std::abort(); - } - } - - Result VerifyBootImagesAndRepairIfNeeded(bool *out_repaired_normal, bool *out_repaired_safe, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { - /* Always set output to false before doing anything else. */ - *out_repaired_normal = false; - *out_repaired_safe = false; - - /* Ensure work buffer is big enough for us to do what we want to do. */ - R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - - /* Get verification state from NAND. */ - VerificationState verification_state; - R_TRY(GetVerificationState(&verification_state, work_buffer, work_buffer_size)); - - /* If we don't need to verify anything, we're done. */ - if (!verification_state.needs_verify_normal && !verification_state.needs_verify_safe) { - return ResultSuccess; - } - - /* Get a session to ncm. */ - DoWithSmSession([&]() { - if (R_FAILED(ncmInitialize())) { - std::abort(); - } - }); - ON_SCOPE_EXIT { ncmExit(); }; - - /* Verify normal, verify safe as needed. */ - if (verification_state.needs_verify_normal) { - R_TRY_CATCH(VerifyBootImagesAndRepairIfNeeded(out_repaired_normal, BootModeType::Normal, work_buffer, work_buffer_size, boot_image_update_type)) { - R_CATCH(ResultUpdaterBootImagePackageNotFound) { - /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ - } - } R_END_TRY_CATCH; - } - - if (verification_state.needs_verify_safe) { - R_TRY_CATCH(VerifyBootImagesAndRepairIfNeeded(out_repaired_safe, BootModeType::Safe, work_buffer, work_buffer_size, boot_image_update_type)) { - R_CATCH(ResultUpdaterBootImagePackageNotFound) { - /* Nintendo considers failure to locate bip a success. TODO: don't do that? */ - } - } R_END_TRY_CATCH; - } - - return ResultSuccess; - } - -} diff --git a/stratosphere/boot/source/updater/updater_api.hpp b/stratosphere/boot/source/updater/updater_api.hpp deleted file mode 100644 index 1baa7e961..000000000 --- a/stratosphere/boot/source/updater/updater_api.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include -#include - -#include "updater_types.hpp" - -namespace sts::updater { - - /* Public API. */ - BootImageUpdateType GetBootImageUpdateType(spl::HardwareType hw_type); - Result VerifyBootImagesAndRepairIfNeeded(bool *out_repaired_normal, bool *out_repaired_safe, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - -} diff --git a/stratosphere/boot/source/updater/updater_bis_management.cpp b/stratosphere/boot/source/updater/updater_bis_management.cpp deleted file mode 100644 index 27912c0e0..000000000 --- a/stratosphere/boot/source/updater/updater_bis_management.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "updater_bis_management.hpp" - -namespace sts::updater { - - Result BisAccessor::Initialize() { - R_TRY(fsOpenBisStorage(&this->storage, this->partition_id)); - this->active = true; - return ResultSuccess; - } - - void BisAccessor::Finalize() { - if (this->active) { - fsStorageClose(&this->storage); - this->active = false; - } - } - - Result BisAccessor::Read(void *dst, size_t size, u64 offset) { - if (offset % SectorAlignment) { - std::abort(); - } - return fsStorageRead(&this->storage, offset, dst, size); - } - - Result BisAccessor::Write(u64 offset, const void *src, size_t size) { - if (offset % SectorAlignment) { - std::abort(); - } - return fsStorageWrite(&this->storage, offset, src, size); - } - - Result BisAccessor::Write(u64 offset, size_t size, const char *bip_path, void *work_buffer, size_t work_buffer_size) { - if (offset % SectorAlignment != 0 || work_buffer_size % SectorAlignment != 0) { - std::abort(); - } - - FILE *bip_fp = fopen(bip_path, "rb"); - if (bip_fp == NULL) { - return ResultUpdaterInvalidBootImagePackage; - } - ON_SCOPE_EXIT { fclose(bip_fp); }; - - size_t written = 0; - while (true) { - std::memset(work_buffer, 0, work_buffer_size); - size_t read_size = fread(work_buffer, 1, work_buffer_size, bip_fp); - if (read_size != work_buffer_size) { - if (ferror(bip_fp)) { - return fsdevGetLastResult(); - } - } - if (written + read_size > size) { - std::abort(); - } - - size_t aligned_size = ((read_size + SectorAlignment - 1) / SectorAlignment) * SectorAlignment; - R_TRY(this->Write(offset + written, work_buffer, aligned_size)); - written += read_size; - - if (read_size != work_buffer_size) { - break; - } - } - return ResultSuccess; - } - - Result BisAccessor::Clear(u64 offset, u64 size, void *work_buffer, size_t work_buffer_size) { - if (offset % SectorAlignment != 0 || work_buffer_size % SectorAlignment != 0) { - std::abort(); - } - - std::memset(work_buffer, 0, work_buffer_size); - - size_t written = 0; - while (written < size) { - size_t cur_write_size = std::min(work_buffer_size, size - written); - R_TRY(this->Write(offset + written, work_buffer, cur_write_size)); - written += cur_write_size; - } - return ResultSuccess; - } - - Result BisAccessor::GetHash(void *dst, u64 offset, u64 size, u64 hash_size, void *work_buffer, size_t work_buffer_size) { - if (offset % SectorAlignment != 0 || work_buffer_size % SectorAlignment != 0) { - std::abort(); - } - - Sha256Context sha_ctx; - sha256ContextCreate(&sha_ctx); - - size_t total_read = 0; - while (total_read < hash_size) { - size_t cur_read_size = std::min(work_buffer_size, size - total_read); - size_t cur_update_size = std::min(cur_read_size, hash_size - total_read); - R_TRY(this->Read(work_buffer, cur_read_size, offset + total_read)); - sha256ContextUpdate(&sha_ctx, work_buffer, cur_update_size); - total_read += cur_read_size; - } - sha256ContextGetHash(&sha_ctx, dst); - - return ResultSuccess; - } - - size_t Boot0Accessor::GetBootloaderVersion(void *bct) { - u32 version = *reinterpret_cast(reinterpret_cast(bct) + BctVersionOffset); - if (version > BctVersionMax) { - std::abort(); - } - - return static_cast(version); - } - - size_t Boot0Accessor::GetEksIndex(size_t bootloader_version) { - if (bootloader_version > BctVersionMax) { - std::abort(); - } - - return (bootloader_version > 0) ? bootloader_version - 1 : 0; - } - - void Boot0Accessor::CopyEks(void *dst_bct, const void *src_eks, size_t eks_index) { - std::memcpy(reinterpret_cast(dst_bct) + BctEksOffset, reinterpret_cast(src_eks) + eks_index * EksEntrySize, EksBlobSize); - } - - Result Boot0Accessor::UpdateEks(void *dst_bct, void *eks_work_buffer) { - size_t read_size; - R_TRY(this->Read(&read_size, eks_work_buffer, EksSize, Boot0Partition::Eks)); - - return this->UpdateEksManually(dst_bct, eks_work_buffer); - } - - Result Boot0Accessor::UpdateEksManually(void *dst_bct, const void *src_eks) { - this->CopyEks(dst_bct, src_eks, GetEksIndex(GetBootloaderVersion(dst_bct))); - return ResultSuccess; - } - - Result Boot0Accessor::PreserveAutoRcm(void *dst_bct, void *work_buffer, Boot0Partition which) { - std::memset(work_buffer, 0, BctSize); - - size_t read_size; - R_TRY(this->Read(&read_size, work_buffer, BctSize, which)); - - void *dst_pubk = reinterpret_cast(reinterpret_cast(dst_bct) + BctPubkOffset); - void *src_pubk = reinterpret_cast(reinterpret_cast(work_buffer) + BctPubkOffset); - std::memcpy(dst_pubk, src_pubk, BctPubkSize); - return ResultSuccess; - } - -} diff --git a/stratosphere/boot/source/updater/updater_bis_management.hpp b/stratosphere/boot/source/updater/updater_bis_management.hpp deleted file mode 100644 index b536e9700..000000000 --- a/stratosphere/boot/source/updater/updater_bis_management.hpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include - -#include "updater_types.hpp" - -namespace sts::updater { - - class BisAccessor { - public: - static constexpr size_t SectorAlignment = 0x200; - private: - FsStorage storage = {}; - FsBisStorageId partition_id; - bool active; - public: - BisAccessor(FsBisStorageId id) : partition_id(id), active(false) { } - ~BisAccessor() { - if (this->active) { - fsStorageClose(&storage); - } - } - - public: - Result Initialize(); - void Finalize(); - protected: - Result Read(void *dst, size_t size, u64 offset); - Result Write(u64 offset, const void *src, size_t size); - Result Write(u64 offset, size_t size, const char *bip_path, void *work_buffer, size_t work_buffer_size); - Result Clear(u64 offset, u64 size, void *work_buffer, size_t work_buffer_size); - Result GetHash(void *dst, u64 offset, u64 size, u64 hash_size, void *work_buffer, size_t work_buffer_size); - }; - - template - struct OffsetSizeEntry { - EnumType which; - u64 offset; - size_t size; - }; - - enum class Boot0Partition { - BctNormalMain, - BctSafeMain, - BctNormalSub, - BctSafeSub, - BctSave, - Package1NormalMain, - Package1NormalSub, - Eks, - Count, - }; - - enum class Boot1Partition { - Package1SafeMain, - Package1SafeSub, - Package1RepairMain, - Package1RepairSub, - Count, - }; - - enum class Package2Partition { - BootConfig, - Package2, - Count, - }; - - struct Boot0Meta { - using EnumType = Boot0Partition; - using OffsetSizeType = OffsetSizeEntry; - - static constexpr size_t NumEntries = static_cast(EnumType::Count); - static constexpr OffsetSizeType Entries[NumEntries] = { - {Boot0Partition::BctNormalMain, 0 * BctSize, BctSize}, - {Boot0Partition::BctSafeMain, 1 * BctSize, BctSize}, - {Boot0Partition::BctNormalSub, 2 * BctSize, BctSize}, - {Boot0Partition::BctSafeSub, 3 * BctSize, BctSize}, - {Boot0Partition::BctSave, 63 * BctSize, BctSize}, - {Boot0Partition::Package1NormalMain, 0x100000, 0x40000}, - {Boot0Partition::Package1NormalSub, 0x140000, 0x40000}, - {Boot0Partition::Eks, 0x180000, EksSize}, - }; - }; - - struct Boot1Meta { - using EnumType = Boot1Partition; - using OffsetSizeType = OffsetSizeEntry; - - static constexpr size_t NumEntries = static_cast(EnumType::Count); - static constexpr OffsetSizeType Entries[NumEntries] = { - {Boot1Partition::Package1SafeMain, 0x00000, 0x40000}, - {Boot1Partition::Package1SafeSub, 0x40000, 0x40000}, - {Boot1Partition::Package1RepairMain, 0x80000, 0x40000}, - {Boot1Partition::Package1RepairSub, 0xC0000, 0x40000}, - }; - }; - - struct Package2Meta { - using EnumType = Package2Partition; - using OffsetSizeType = OffsetSizeEntry; - - static constexpr size_t NumEntries = static_cast(EnumType::Count); - static constexpr OffsetSizeType Entries[NumEntries] = { - {Package2Partition::BootConfig, 0x0000, 0x004000}, - {Package2Partition::Package2, 0x4000, 0x7FC000}, - }; - }; - - template - class PartitionAccessor : public BisAccessor { - public: - using EnumType = typename Meta::EnumType; - using OffsetSizeType = typename Meta::OffsetSizeType; - public: - PartitionAccessor(FsBisStorageId id) : BisAccessor(id) { } - private: - constexpr const OffsetSizeType *FindEntry(EnumType which) { - for (size_t i = 0; i < Meta::NumEntries; i++) { - if (Meta::Entries[i].which == which) { - return &Meta::Entries[i]; - } - } - std::abort(); - } - public: - Result Read(size_t *out_size, void *dst, size_t size, EnumType which) { - const auto entry = FindEntry(which); - if (size < entry->size) { - std::abort(); - } - - R_TRY(BisAccessor::Read(dst, entry->size, entry->offset)); - - *out_size = entry->size; - return ResultSuccess; - } - - Result Write(const void *src, size_t size, EnumType which) { - const auto entry = FindEntry(which); - if (size > entry->size || size % BisAccessor::SectorAlignment != 0) { - std::abort(); - } - - return BisAccessor::Write(entry->offset, src, size); - } - - Result Write(const char *bip_path, void *work_buffer, size_t work_buffer_size, EnumType which) { - const auto entry = FindEntry(which); - return BisAccessor::Write(entry->offset, entry->size, bip_path, work_buffer, work_buffer_size); - } - - Result Clear(void *work_buffer, size_t work_buffer_size, EnumType which) { - const auto entry = FindEntry(which); - return BisAccessor::Clear(entry->offset, entry->size, work_buffer, work_buffer_size); - } - - Result GetHash(void *dst, u64 hash_size, void *work_buffer, size_t work_buffer_size, EnumType which) { - const auto entry = FindEntry(which); - return BisAccessor::GetHash(dst, entry->offset, entry->size, hash_size, work_buffer, work_buffer_size); - } - }; - - enum class Package2Type { - NormalMain, - NormalSub, - SafeMain, - SafeSub, - RepairMain, - RepairSub, - }; - - static constexpr FsBisStorageId GetPackage2StorageId(Package2Type which) { - switch (which) { - case Package2Type::NormalMain: - return FsBisStorageId_BootConfigAndPackage2NormalMain; - case Package2Type::NormalSub: - return FsBisStorageId_BootConfigAndPackage2NormalSub; - case Package2Type::SafeMain: - return FsBisStorageId_BootConfigAndPackage2SafeMain; - case Package2Type::SafeSub: - return FsBisStorageId_BootConfigAndPackage2SafeSub; - case Package2Type::RepairMain: - return FsBisStorageId_BootConfigAndPackage2RepairMain; - case Package2Type::RepairSub: - return FsBisStorageId_BootConfigAndPackage2RepairSub; - default: - std::abort(); - } - } - - class Boot0Accessor : public PartitionAccessor { - public: - static constexpr FsBisStorageId PartitionId = FsBisStorageId_Boot0; - static constexpr size_t BctPubkOffset = 0x210; - static constexpr size_t BctPubkSize = 0x100; - static constexpr size_t BctEksOffset = 0x450; - static constexpr size_t BctVersionOffset = 0x2330; - static constexpr size_t BctVersionMax = 0x20; - public: - Boot0Accessor() : PartitionAccessor(PartitionId) { } - private: - static size_t GetBootloaderVersion(void *bct); - static size_t GetEksIndex(size_t bootloader_version); - static void CopyEks(void *dst_bct, const void *src_eks, size_t eks_index); - public: - Result UpdateEks(void *dst_bct, void *eks_work_buffer); - Result UpdateEksManually(void *dst_bct, const void *src_eks); - Result PreserveAutoRcm(void *dst_bct, void *work_buffer, Boot0Partition which); - }; - - class Boot1Accessor : public PartitionAccessor { - public: - static constexpr FsBisStorageId PartitionId = FsBisStorageId_Boot1; - public: - Boot1Accessor() : PartitionAccessor(PartitionId) { } - }; - - class Package2Accessor : public PartitionAccessor { - public: - Package2Accessor(Package2Type which) : PartitionAccessor(GetPackage2StorageId(which)) { } - }; - -} diff --git a/stratosphere/boot/source/updater/updater_bis_save.cpp b/stratosphere/boot/source/updater/updater_bis_save.cpp deleted file mode 100644 index a06158763..000000000 --- a/stratosphere/boot/source/updater/updater_bis_save.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "updater_bis_save.hpp" - -namespace sts::updater { - - size_t BisSave::GetVerificationFlagOffset(BootModeType mode) { - switch (mode) { - case BootModeType::Normal: - return 0; - case BootModeType::Safe: - return 1; - default: - return 2; - } - } - - Result BisSave::Initialize(void *work_buffer, size_t work_buffer_size) { - if (work_buffer_size < SaveSize || reinterpret_cast(work_buffer) & 0xFFF || work_buffer_size & 0x1FF) { - std::abort(); - } - - R_TRY(this->accessor.Initialize()); - this->save_buffer = work_buffer; - return ResultSuccess; - } - - void BisSave::Finalize() { - this->accessor.Finalize(); - } - - Result BisSave::Load() { - size_t read_size; - return this->accessor.Read(&read_size, this->save_buffer, SaveSize, Boot0Partition::BctSave); - } - - Result BisSave::Save() { - return this->accessor.Write(this->save_buffer, SaveSize, Boot0Partition::BctSave); - } - - bool BisSave::GetNeedsVerification(BootModeType mode) { - return reinterpret_cast(this->save_buffer)[GetVerificationFlagOffset(mode)] != 0; - } - - void BisSave::SetNeedsVerification(BootModeType mode, bool needs_verification) { - reinterpret_cast(this->save_buffer)[GetVerificationFlagOffset(mode)] = needs_verification ? 1 : 0; - } - -} diff --git a/stratosphere/boot/source/updater/updater_bis_save.hpp b/stratosphere/boot/source/updater/updater_bis_save.hpp deleted file mode 100644 index fdddca2dc..000000000 --- a/stratosphere/boot/source/updater/updater_bis_save.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include - -#include "updater_types.hpp" -#include "updater_bis_management.hpp" - -namespace sts::updater { - - class BisSave { - public: - static constexpr size_t SaveSize = BctSize; - private: - Boot0Accessor accessor; - void *save_buffer; - public: - BisSave() : save_buffer(nullptr) { } - private: - static size_t GetVerificationFlagOffset(BootModeType mode); - public: - Result Initialize(void *work_buffer, size_t work_buffer_size); - void Finalize(); - - Result Load(); - Result Save(); - bool GetNeedsVerification(BootModeType mode); - void SetNeedsVerification(BootModeType mode, bool needs_verification); - }; - -} diff --git a/stratosphere/boot/source/updater/updater_files.cpp b/stratosphere/boot/source/updater/updater_files.cpp deleted file mode 100644 index 759d4abb3..000000000 --- a/stratosphere/boot/source/updater/updater_files.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "updater_api.hpp" - -namespace sts::updater { - - Result ReadFile(size_t *out_size, void *dst, size_t dst_size, const char *path) { - FILE *fp = fopen(path, "rb"); - if (fp == NULL) { - return ResultUpdaterInvalidBootImagePackage; - } - ON_SCOPE_EXIT { fclose(fp); }; - - std::memset(dst, 0, dst_size); - size_t read_size = fread(dst, 1, dst_size, fp); - if (ferror(fp)) { - return fsdevGetLastResult(); - } - *out_size = read_size; - return ResultSuccess; - } - - Result GetFileHash(size_t *out_size, void *dst_hash, const char *path, void *work_buffer, size_t work_buffer_size) { - FILE *fp = fopen(path, "rb"); - if (fp == NULL) { - return ResultUpdaterInvalidBootImagePackage; - } - ON_SCOPE_EXIT { fclose(fp); }; - - Sha256Context sha_ctx; - sha256ContextCreate(&sha_ctx); - - size_t total_size = 0; - while (true) { - size_t read_size = fread(work_buffer, 1, work_buffer_size, fp); - if (ferror(fp)) { - return fsdevGetLastResult(); - } - if (read_size == 0) { - break; - } - - sha256ContextUpdate(&sha_ctx, work_buffer, read_size); - total_size += read_size; - if (read_size != work_buffer_size) { - break; - } - } - - sha256ContextGetHash(&sha_ctx, dst_hash); - *out_size = total_size; - return ResultSuccess; - } - -} diff --git a/stratosphere/boot/source/updater/updater_files.hpp b/stratosphere/boot/source/updater/updater_files.hpp deleted file mode 100644 index 0c1fb320e..000000000 --- a/stratosphere/boot/source/updater/updater_files.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include - -#include "updater_types.hpp" - -namespace sts::updater { - - /* File helpers. */ - Result ReadFile(size_t *out_size, void *dst, size_t dst_size, const char *path); - Result GetFileHash(size_t *out_size, void *dst_hash, const char *path, void *work_buffer, size_t work_buffer_size); - -} diff --git a/stratosphere/boot/source/updater/updater_paths.cpp b/stratosphere/boot/source/updater/updater_paths.cpp deleted file mode 100644 index 3fa4920b6..000000000 --- a/stratosphere/boot/source/updater/updater_paths.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "updater_paths.hpp" - -namespace sts::updater { - - namespace { - - /* Actual paths. */ - constexpr const char *BootImagePackageMountPath = "bip"; - constexpr const char *BctPathNx = "bip:/nx/bct"; - constexpr const char *Package1PathNx = "bip:/nx/package1"; - constexpr const char *Package2PathNx = "bip:/nx/package2"; - constexpr const char *BctPathA = "bip:/a/bct"; - constexpr const char *Package1PathA = "bip:/a/package1"; - constexpr const char *Package2PathA = "bip:/a/package2"; - - const char *ChooseCandidatePath(const char * const *candidates, size_t num_candidates) { - if (num_candidates == 0) { - std::abort(); - } - - for (size_t i = 0; i < num_candidates; i++) { - struct stat buf; - if (stat(candidates[i], &buf) != 0) { - continue; - } - - if (!S_ISREG(buf.st_mode)) { - continue; - } - - return candidates[i]; - } - - /* Nintendo just uses the last candidate if they all fail...should we abort? */ - return candidates[num_candidates - 1]; - } - - } - - const char *GetBootImagePackageMountPath() { - return BootImagePackageMountPath; - } - - - const char *GetBctPath(BootImageUpdateType boot_image_update_type) { - switch (boot_image_update_type) { - case BootImageUpdateType::Erista: - { - constexpr const char *candidates[] = {BctPathNx}; - return ChooseCandidatePath(candidates, sizeof(candidates) / sizeof(candidates[0])); - } - case BootImageUpdateType::Mariko: - { - constexpr const char *candidates[] = {BctPathA, BctPathNx}; - return ChooseCandidatePath(candidates, sizeof(candidates) / sizeof(candidates[0])); - } - default: - std::abort(); - } - } - - const char *GetPackage1Path(BootImageUpdateType boot_image_update_type) { - switch (boot_image_update_type) { - case BootImageUpdateType::Erista: - { - constexpr const char *candidates[] = {Package1PathNx}; - return ChooseCandidatePath(candidates, sizeof(candidates) / sizeof(candidates[0])); - } - case BootImageUpdateType::Mariko: - { - constexpr const char *candidates[] = {Package1PathA, Package1PathNx}; - return ChooseCandidatePath(candidates, sizeof(candidates) / sizeof(candidates[0])); - } - default: - std::abort(); - } - } - - const char *GetPackage2Path(BootImageUpdateType boot_image_update_type) { - switch (boot_image_update_type) { - case BootImageUpdateType::Erista: - { - constexpr const char *candidates[] = {Package2PathNx}; - return ChooseCandidatePath(candidates, sizeof(candidates) / sizeof(candidates[0])); - } - case BootImageUpdateType::Mariko: - { - constexpr const char *candidates[] = {Package2PathA, Package2PathNx}; - return ChooseCandidatePath(candidates, sizeof(candidates) / sizeof(candidates[0])); - } - default: - std::abort(); - } - } - -} - - - diff --git a/stratosphere/boot/source/updater/updater_paths.hpp b/stratosphere/boot/source/updater/updater_paths.hpp deleted file mode 100644 index 2197b35b1..000000000 --- a/stratosphere/boot/source/updater/updater_paths.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include - -#include "updater_types.hpp" - -namespace sts::updater { - - /* Path functionality. */ - const char *GetBootImagePackageMountPath(); - const char *GetBctPath(BootImageUpdateType boot_image_update_type); - const char *GetPackage1Path(BootImageUpdateType boot_image_update_type); - const char *GetPackage2Path(BootImageUpdateType boot_image_update_type); - -} diff --git a/stratosphere/boot/source/updater/updater_types.hpp b/stratosphere/boot/source/updater/updater_types.hpp deleted file mode 100644 index 6abd7cd8d..000000000 --- a/stratosphere/boot/source/updater/updater_types.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2018-2019 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include -#include - -namespace sts::updater { - - /* Types. */ - enum class BootImageUpdateType { - Erista, - Mariko, - }; - - enum class BootModeType { - Normal, - Safe, - }; - - struct VerificationState { - bool needs_verify_normal; - bool needs_verify_safe; - }; - - /* Convenience size definitions. */ - constexpr size_t BctSize = 0x4000; - constexpr size_t EksSize = 0x4000; - constexpr size_t EksEntrySize = 0x200; - constexpr size_t EksBlobSize = 0xB0; - -} \ No newline at end of file diff --git a/stratosphere/libstratosphere b/stratosphere/libstratosphere index ca344e1d1..f575d0644 160000 --- a/stratosphere/libstratosphere +++ b/stratosphere/libstratosphere @@ -1 +1 @@ -Subproject commit ca344e1d19267779a59b6a212683792538bb76af +Subproject commit f575d0644635582d83d484e7fc9691f6c17630b1