fs: utilities for hac2l to print gc headers
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user