fs: utilities for hac2l to print gc headers

This commit is contained in:
Michael Scire
2022-03-14 14:26:45 -07:00
committed by SciresM
parent 2d984822c6
commit c35114bacc
15 changed files with 893 additions and 3 deletions

View File

@@ -38,7 +38,7 @@ namespace ams::fs {
GameCardAttribute_DifferentRegionCupToTerraDeviceFlag = (1 << 3),
GameCardAttribute_DifferentRegionCupToGlobalDeviceFlag = (1 << 4),
GameCardAttribute_HasHeaderSign2Flag = (1 << 7),
GameCardAttribute_HasCa10CertificateFlag = (1 << 7),
};
enum class GameCardCompatibilityType : u8 {

View File

@@ -40,8 +40,17 @@ namespace ams::gc::impl {
static const void *s_ca10_modulus;
static const void *s_ca10_certificate_modulus;
static const void *s_card_header_key;
private:
static constinit inline u8 s_titlekey_keks[GcCrypto::GcTitleKeyKekIndexMax][GcCrypto::GcAesKeyLength] = {};
public:
static Result SetLibraryEmbeddedKeys(bool is_dev = GcCrypto::CheckDevelopmentSpl());
static void SetLibraryTitleKeyKek(size_t kek_index, const void *kek, size_t kek_size) {
AMS_ASSERT(kek_index < GcCrypto::GcTitleKeyKekIndexMax);
AMS_ASSERT(kek_size == GcCrypto::GcAesKeyLength);
std::memcpy(s_titlekey_keks[kek_index], kek, sizeof(s_titlekey_keks[kek_index]));
}
private:
static Result DecryptoEmbeddedKeys(ConcatenatedGcLibraryEmbeddedKeys *out, size_t out_size, bool is_dev = GcCrypto::CheckDevelopmentSpl());
};

View File

@@ -29,6 +29,7 @@ namespace ams::gc::impl {
static constexpr size_t GcAesCbcIvLength = crypto::Aes128CbcEncryptor::IvSize;
static constexpr size_t GcHmacKeyLength = 0x20;
static constexpr size_t GcCvConstLength = 0x10;
static constexpr size_t GcTitleKeyKekIndexMax = 0x10;
static constexpr size_t GcSha256HashLength = crypto::Sha256Generator::HashSize;
public:
static bool CheckDevelopmentSpl();
@@ -42,6 +43,8 @@ namespace ams::gc::impl {
static Result VerifyT1CardCertificate(const void *cert_buffer, size_t cert_size);
static Result VerifyCa10Certificate(const void *cert_buffer, size_t cert_size);
static Result DecryptCardInitialData(void *dst, size_t dst_size, const void *initial_data, size_t data_size, size_t kek_index);
};
}

View File

@@ -35,8 +35,22 @@ namespace ams::gc::impl {
static_assert(util::is_pod<CardInitialData>::value);
static_assert(sizeof(CardInitialData) == 0x200);
enum FwVersion : u8 {
FwVersion_ForDev = 0,
FwVersion_1_0_0 = 1,
FwVersion_4_0_0 = 2,
FwVersion_9_0_0 = 3,
FwVersion_11_0_0 = 4,
FwVersion_12_0_0 = 5,
};
enum KekIndex : u8 {
KekIndex_Version0 = 0,
KekIndex_VersionForDev = 1,
};
struct CardHeaderKeyIndex {
using KekIndex = util::BitPack8::Field<0, 4, u8>;
using KekIndex = util::BitPack8::Field<0, 4, gc::impl::KekIndex>;
using TitleKeyDecIndex = util::BitPack8::Field<KekIndex::Next, 4, u8>;
static_assert(TitleKeyDecIndex::Next == BITSIZEOF(u8));
@@ -76,6 +90,11 @@ namespace ams::gc::impl {
AccessControl1ClockRate_50MHz = 0x00A10010,
};
enum SelSec : u8 {
SelSec_T1 = 1,
SelSec_T2 = 2,
};
struct CardHeader {
static constexpr u32 Magic = util::FourCC<'H','E','A','D'>::Code;
@@ -135,8 +154,9 @@ namespace ams::gc::impl {
struct Ca10Certificate {
u8 signature[crypto::Rsa2048Pkcs1Sha256Verifier::SignatureSize];
u8 unk_100[0x200];
u8 unk_100[0x30];
u8 modulus[crypto::Rsa2048Pkcs1Sha256Verifier::ModulusSize];
u8 unk_230[0x1D0];
};
static_assert(util::is_pod<Ca10Certificate>::value);
static_assert(sizeof(Ca10Certificate) == 0x400);