FalsifyTwlBackup:BkpType Legacy に対応。

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_test_tools@38 6b0af911-cb57-b745-895f-eec5701120e1
This commit is contained in:
n2460 2011-10-27 11:50:55 +00:00
parent 4978389346
commit 12cf32bf6b
2 changed files with 114 additions and 43 deletions

View File

@ -23,6 +23,10 @@ namespace TwlBackupBlock
// for WithPrivateSave
public const int RESERVED_SIZE_FOR_WPS = 12;
// for Legacy
public const int RESERVED_SIZE_FOR_LEGACY = 4;
public const int NUM_OF_SECTION_LEGACY = 4;
public UInt32 signature;
public UInt16 companyCode;
public UInt16 version;
@ -41,6 +45,10 @@ namespace TwlBackupBlock
public UInt32 privateSaveForWPS;
public readonly Byte[] reservedForWPS;
// for Legacy
public UInt32 contentIdForLegacy;
public UInt16 contentIndexForLegacy;
private BkpType type;
private int headerSize;
@ -72,12 +80,19 @@ namespace TwlBackupBlock
uniqueId = new Byte[UNIQUE_ID_SIZE];
hardwareId = new Byte[HARDWARE_ID_SIZE];
fileSizes = new UInt32[NUM_OF_SECTION];
contentId = new UInt32[MAX_CONTENTS];
contentIndex = new UInt16[MAX_CONTENTS];
if (type != BkpType.LEGACY)
{
fileSizes = new UInt32[NUM_OF_SECTION];
contentId = new UInt32[MAX_CONTENTS];
contentIndex = new UInt16[MAX_CONTENTS];
reserved = new Byte[RESERVED_SIZE];
}
else
{
fileSizes = new UInt32[NUM_OF_SECTION_LEGACY];
reserved = new Byte[RESERVED_SIZE_FOR_LEGACY];
}
tmdReserved = new TmdReserved();
reserved = new Byte[RESERVED_SIZE];
if (type == BkpType.WITH_PRIVATE_SAVE)
{
reservedForWPS = new Byte[RESERVED_SIZE_FOR_WPS];
@ -154,7 +169,6 @@ namespace TwlBackupBlock
using (var ms = new MemoryStream(bytes))
using (var bw = new BinaryWriter(ms))
{
// TODO : Legacy 対応
bw.Write(signature);
bw.Write(companyCode);
bw.Write(version);
@ -166,16 +180,33 @@ namespace TwlBackupBlock
{
bw.Write(e);
}
foreach (UInt32 e in contentId)
if (type != BkpType.LEGACY)
{
bw.Write(e);
foreach (UInt32 e in contentId)
{
bw.Write(e);
}
}
foreach (UInt16 e in contentIndex)
else
{
bw.Write(e);
bw.Write(contentIdForLegacy);
}
if (type != BkpType.LEGACY)
{
foreach (UInt16 e in contentIndex)
{
bw.Write(e);
}
}
bw.Write(tmdReserved.GetBytes());
bw.Write(headerVersion);
if (type == BkpType.LEGACY)
{
bw.Write(contentIndexForLegacy);
}
if (type != BkpType.LEGACY)
{
bw.Write(headerVersion);
}
bw.Write(reserved);
if (type == BkpType.WITH_PRIVATE_SAVE)
{
@ -204,7 +235,6 @@ namespace TwlBackupBlock
using (var ms = new MemoryStream(bytes))
using (var br = new ExtBinaryReader(ms))
{
// TODO : Legacy 対応
br.Read(ref signature);
br.Read(ref companyCode);
br.Read(ref version);
@ -213,14 +243,31 @@ namespace TwlBackupBlock
br.Read(ref titleId);
br.Read(ref requiredSize);
br.Read(fileSizes);
br.Read(contentId);
br.Read(contentIndex);
if (type != BkpType.LEGACY)
{
br.Read(contentId);
}
else
{
br.Read(ref contentIdForLegacy);
}
if (type != BkpType.LEGACY)
{
br.Read(contentIndex);
}
{
byte[] tmdReservedBytes = new byte[TMD_RESERVED_SIZE];
br.Read(tmdReservedBytes);
tmdReserved.SetBytes(tmdReservedBytes);
}
br.Read(ref headerVersion);
if (type == BkpType.LEGACY)
{
br.Read(ref contentIndexForLegacy);
}
if (type != BkpType.LEGACY)
{
br.Read(ref headerVersion);
}
br.Read(reserved);
if (type == BkpType.WITH_PRIVATE_SAVE)
{

View File

@ -23,6 +23,17 @@ namespace TwlBackupBlock
PRIVATE_SAVE
};
// いまいち・・・
public const int MAX_CONTENTS_LEGACY = 1;
public enum SectionIndexLegacy
{
TMD,
CONTENT,
PUBLIC_SAVE = CONTENT + MAX_CONTENTS_LEGACY,
SUB_BANNER,
PRIVATE_SAVE
};
private const int KEY_SIZE = 16;
private const int ROUND_SCALE = 16;
@ -41,8 +52,10 @@ namespace TwlBackupBlock
private const int ENCRYPT_BANNER_SIZE = BANNER_SIZE + AES_SIGN_HEADER_SIZE;
private const int ENCRYPT_HEADER_SIZE = HEADER_SIZE + AES_SIGN_HEADER_SIZE;
private const int ENCRYPT_EX_HEADER_SIZE = EX_HEADER_SIZE + AES_SIGN_HEADER_SIZE;
private const int ENCRYPT_LEGACY_HEADER_SIZE = LEGACY_HEADER_SIZE + AES_SIGN_HEADER_SIZE;
private const int ENCRYPT_SIGNATURE_SIZE = SIGNATURE_SIZE + AES_SIGN_HEADER_SIZE;
private const int ENCRYPT_EX_SIGNATURE_SIZE = EX_SIGNATURE_SIZE + AES_SIGN_HEADER_SIZE;
private const int ENCRYPT_LEGACY_SIGNATURE_SIZE = LEGACY_SIGNATURE_SIZE + AES_SIGN_HEADER_SIZE;
/// <summary>
/// バックアップデータをブロックに分割して復号化をおこないます。
@ -53,17 +66,13 @@ namespace TwlBackupBlock
/// <returns>分割、復号化されたブロック。</returns>
public static Blocks DecryptBackupData(byte[] data, byte[] key, BkpType type)
{
// TODO : Legacy 対応
if (type == BkpType.LEGACY)
{
Console.WriteLine("Legacy には未対応です。");
return null;
}
int headerSize = 0;
int signatureSize = 0;
int encryptHeaderSize = 0;
int encryptSignatureSize = 0;
int contentsNum = MAX_CONTENTS;
int indexPublicSave = (int)SectionIndexLegacy.PUBLIC_SAVE;
int indexSubBanner = (int)SectionIndexLegacy.SUB_BANNER;
switch (type)
{
@ -80,6 +89,16 @@ namespace TwlBackupBlock
encryptHeaderSize = ENCRYPT_EX_HEADER_SIZE;
encryptSignatureSize = ENCRYPT_EX_SIGNATURE_SIZE;
break;
case BkpType.LEGACY:
headerSize = LEGACY_HEADER_SIZE;
signatureSize = LEGACY_SIGNATURE_SIZE;
encryptHeaderSize = ENCRYPT_LEGACY_HEADER_SIZE;
encryptSignatureSize = ENCRYPT_LEGACY_SIGNATURE_SIZE;
contentsNum = MAX_CONTENTS_LEGACY;
indexPublicSave = (int)SectionIndexLegacy.PUBLIC_SAVE;
indexSubBanner = (int)SectionIndexLegacy.SUB_BANNER;
break;
}
if (data == null)
@ -122,15 +141,14 @@ namespace TwlBackupBlock
blocks.signature.body = new SignatureBody(
DecryptBlock(br, signatureSize, key, out blocks.signature.mac, out blocks.signature.iv), type);
// TODO : Legacy 対応
int TMD_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.TMD];
int[] CONTENT_SIZE = new int[MAX_CONTENTS];
for (int i = 0; i < MAX_CONTENTS; i++)
int[] CONTENT_SIZE = new int[contentsNum];
for (int i = 0; i < contentsNum; i++)
{
CONTENT_SIZE[i] = (int)headerBody.fileSizes[(int)SectionIndex.CONTENT + i];
}
int PUBLIC_SAVE_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.PUBLIC_SAVE];
int SUB_BANNER_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.SUB_BANNER];
int PUBLIC_SAVE_SIZE = (int)headerBody.fileSizes[indexPublicSave];
int SUB_BANNER_SIZE = (int)headerBody.fileSizes[indexSubBanner];
int PRIVATE_SAVE_SIZE = 0;
if (type == BkpType.WITH_PRIVATE_SAVE)
{
@ -138,7 +156,7 @@ namespace TwlBackupBlock
}
blocks.tmd.body = new Body(DecryptBlock(br, TMD_SIZE, key, out blocks.tmd.mac, out blocks.tmd.iv));
for (int i = 0; i < MAX_CONTENTS; i++)
for (int i = 0; i < contentsNum; i++)
{
if (CONTENT_SIZE[i] > 0)
{
@ -393,17 +411,13 @@ namespace TwlBackupBlock
/// <returns>検証に成功した場合はtrue。それ以外の場合はfalse。</returns>
public static bool Verify(byte[] data, byte[] aesCbcKey, byte[] aesCmacKey, BkpType type)
{
// TODO : Legacy 対応
if (type == BkpType.LEGACY)
{
Console.WriteLine("Legacy には未対応です。");
return false;
}
int headerSize = 0;
int signatureSize = 0;
int encryptHeaderSize = 0;
int encryptSignatureSize = 0;
int contentsNum = MAX_CONTENTS;
int indexPublicSave = (int)SectionIndex.PUBLIC_SAVE;
int indexSubBanner = (int)SectionIndex.SUB_BANNER;
switch (type)
{
@ -420,6 +434,16 @@ namespace TwlBackupBlock
encryptHeaderSize = ENCRYPT_EX_HEADER_SIZE;
encryptSignatureSize = ENCRYPT_EX_SIGNATURE_SIZE;
break;
case BkpType.LEGACY:
headerSize = LEGACY_HEADER_SIZE;
signatureSize = LEGACY_SIGNATURE_SIZE;
encryptHeaderSize = ENCRYPT_LEGACY_HEADER_SIZE;
encryptSignatureSize = ENCRYPT_LEGACY_SIGNATURE_SIZE;
contentsNum = MAX_CONTENTS_LEGACY;
indexPublicSave = (int)SectionIndexLegacy.PUBLIC_SAVE;
indexSubBanner = (int)SectionIndexLegacy.SUB_BANNER;
break;
}
if (data == null)
@ -492,13 +516,13 @@ namespace TwlBackupBlock
// TODO : Legacy 対応
int TMD_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.TMD];
int[] CONTENT_SIZE = new int[MAX_CONTENTS];
for (int i = 0; i < MAX_CONTENTS; i++)
int[] CONTENT_SIZE = new int[contentsNum];
for (int i = 0; i < contentsNum; i++)
{
CONTENT_SIZE[i] = (int)headerBody.fileSizes[(int)SectionIndex.CONTENT + i];
}
int PUBLIC_SAVE_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.PUBLIC_SAVE];
int SUB_BANNER_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.SUB_BANNER];
int PUBLIC_SAVE_SIZE = (int)headerBody.fileSizes[indexPublicSave];
int SUB_BANNER_SIZE = (int)headerBody.fileSizes[indexSubBanner];
int PRIVATE_SAVE_SIZE = 0;
if (type == BkpType.WITH_PRIVATE_SAVE)
{
@ -508,7 +532,7 @@ namespace TwlBackupBlock
int restSize = RoundUp(TMD_SIZE, ROUND_SCALE) +
RoundUp(PUBLIC_SAVE_SIZE, ROUND_SCALE) + RoundUp(SUB_BANNER_SIZE, ROUND_SCALE) +
AES_SIGN_HEADER_SIZE * 3;
for (int i = 0; i < MAX_CONTENTS; i++)
for (int i = 0; i < contentsNum; i++)
{
if (CONTENT_SIZE[i] > 0)
{
@ -536,7 +560,7 @@ namespace TwlBackupBlock
Console.WriteLine("TMDブロックのハッシュが一致しません");
return false;
}
for (int i = 0; i < MAX_CONTENTS; i++)
for (int i = 0; i < contentsNum; i++)
{
if (CONTENT_SIZE[i] > 0)
{
@ -560,7 +584,7 @@ namespace TwlBackupBlock
Console.WriteLine("publicセーブデータブロックのMACが一致しません");
return false;
}
if (!CheckHash(blocks.publicSave, signatureBody.digest.section[(int)SectionIndex.PUBLIC_SAVE]))
if (!CheckHash(blocks.publicSave, signatureBody.digest.section[indexPublicSave]))
{
Console.WriteLine("publicセーブデータブロックのハッシュが一致しません");
return false;
@ -571,7 +595,7 @@ namespace TwlBackupBlock
Console.WriteLine("サブバナーブロックの内容とMACが一致しません");
return false;
}
if (!CheckHash(blocks.subBanner, signatureBody.digest.section[(int)SectionIndex.SUB_BANNER]))
if (!CheckHash(blocks.subBanner, signatureBody.digest.section[indexSubBanner]))
{
Console.WriteLine("サブバナーブロックのハッシュが一致しません");
return false;