From 217a112a59462ab2ccf5490171d9d5d795857f8e Mon Sep 17 00:00:00 2001 From: n2460 Date: Sat, 22 Oct 2011 11:48:57 +0000 Subject: [PATCH] =?UTF-8?q?FalsifyTwlBackup:=E6=94=B9=E3=81=96=E3=82=93?= =?UTF-8?q?=E5=87=A6=E7=90=86=E9=83=A8=E3=82=92=E5=88=A5=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=AB=E5=88=86=E9=9B=A2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_test_tools@32 6b0af911-cb57-b745-895f-eec5701120e1 --- .../Windows/FalsifyTwlBackup/Falsify.cs | 403 ++++++++++++++++++ .../FalsifyTwlBackup/FalsifyTwlBackup.csproj | 1 + 2 files changed, 404 insertions(+) create mode 100644 TwlBkpCheck/Windows/FalsifyTwlBackup/Falsify.cs diff --git a/TwlBkpCheck/Windows/FalsifyTwlBackup/Falsify.cs b/TwlBkpCheck/Windows/FalsifyTwlBackup/Falsify.cs new file mode 100644 index 0000000..1ce4a65 --- /dev/null +++ b/TwlBkpCheck/Windows/FalsifyTwlBackup/Falsify.cs @@ -0,0 +1,403 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; +using System.Diagnostics; +using TwlBackupBlock; + +namespace FalsifyTwlBackup +{ +partial class Program +{ + /// + /// 指定されたbyteサイズで、0のみのbyte列を作成します。 + /// + /// 作成するデータのサイズ[単位:byte] + /// 作成したデータのbyte列 + // TODO 不正データの作成方法を選べるようにしてもいいかも + static byte[] CreateImproperData(int dataSize) + { + byte[] data = new byte[dataSize]; + for (int i = 0; i < data.Length; i++) + { + //data[i] = (byte)(i); + data[i] = 0; + } + return data; + } + + /// + /// データの差し替えを行います。 + /// + /// 上書き対象となるデータ本体 + /// 上書きする不正データ + static void ReplaceImproperData(AbstractBody dataBlocks, byte[] impData) + { + for (int i = 0; i < impData.Length; i++) + { + if (i < dataBlocks.Length) // 上書き先のデータサイズを超えませんように + { + dataBlocks[i] = impData[i]; + } + } + return; + } + + /// + /// ※未使用 + /// 暗号化に使用するIVを作成します。 + /// AES方式で、ブロックサイズはAES_BLOCK_SIZE[bit]と同じです。 + /// + /// 生成したivのbyte列 + static byte[] GenerateNewIv() + { + // 暗号化用IV作成 + /* + * [参考] C#(.NET Framework)のAESを使ってファイルを暗号化してみる + * http://hibara.sblo.jp/article/43505136.html + */ + System.Security.Cryptography.AesCryptoServiceProvider + aes = new System.Security.Cryptography.AesCryptoServiceProvider(); + aes.BlockSize = AES_BLOCK_SIZE; // AESはブロックサイズ、キー長ともに16byte + aes.GenerateIV(); // IVの設定(ブロックサイズと同サイズ = 16byte) + byte[] byteIV = aes.IV; // IVをバイト列に + return byteIV; + } + + /// + /// 署名のハッシュセットを変更します。 + /// + /// 変更対象となる署名ブロックを有するBlocks + /// 新しいハッシュ値 + /// 変更するブロックセクション + static void ChangeHashSet(Blocks dataBlocks, byte[] hash, int section) + { + Debug.Assert((section <= BLOCK_NUM - 1) && (section >= 0)); + + SignatureBody signature; + signature = (SignatureBody)dataBlocks.signature.body; + if (SECTION_CONTENT <= section && section < SECTION_CONTENT + MAX_CONTENTS) + { + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.CONTENT + section - SECTION_CONTENT], 0); + } + else + { + switch (section) + { + case SECTION_BANNER: + hash.CopyTo(signature.digest.banner, 0); + break; + + case SECTION_HEADER: + hash.CopyTo(signature.digest.header, 0); + break; + + case SECTION_TMD: + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.TMD], 0); + break; + + case SECTION_PUBLIC_SAVE: + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.PUBLIC_SAVE], 0); + break; + + case SECTION_SUB_BANNER: + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.SUB_BANNER], 0); + break; + + case SECTION_PRIVATE_SAVE: + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.PRIVATE_SAVE], 0); + break; + + default: + Debug.Assert(false); + break; + } + } + } + + /// + /// byte列を結合します。 + /// + /// 前半部分に来るbyte列 + /// 後半部分に来るbyte列 + /// 連結後のbyte列 + static byte[] MergeByteArray(byte[] front, byte[] rear) + { + return front.Concat(rear).ToArray(); + } + + /// + /// byte列をbinファイルに出力します。 + /// + /// ファイル名となる改ざんパターンの番号 + /// 出力ディレクトリのパス + /// ファイルに出力するデータ + static void OutputFalsifiedData(int improperNo, string outFolderPath, byte[] data) + { + string outFalsifiedDataPath = Convert.ToString(improperNo) + EXTENSION; // ファイル名を改ざん番号から生成 + outFalsifiedDataPath = Path.Combine(outFolderPath, outFalsifiedDataPath); // 出力ディレクトリとファイル名を結合 + File.WriteAllBytes(outFalsifiedDataPath, data); // 出力 + } + + /// + /// データ本体とMACとIVをひとつのブロックに結合します。 + /// 必要に応じて不正データを挿入します。 + /// + /// 暗号化するBlockを持つBlocks + /// 暗号化するBlockのセクション + /// バックアップデータに関するインスタンス + /// 挿入する不正データ + /// 挿入する位置 + /// 格納するMAC + /// MACを算出するためのハッシュ値 + /// データ本体、MAC、IVを順に結合したbyte列 + static byte[] EncryptBlock(Blocks dataBlocks, int section, Properties prop, byte[] impData, int insertPos, byte[] byteMac, byte[] byteHash = null) + { + byte[] encryptedBlock = new byte[0]; + + // (データ本体の前に不正データ挿入) + if (insertPos >= FRONT_BANNER && insertPos <= FRONT_SUB_BANNER) + { + if (section == insertPos - FRONT_BANNER) + { + encryptedBlock = MergeByteArray(encryptedBlock, impData); + } + } + + // データ本体を暗号化 + encryptedBlock = MergeByteArray(encryptedBlock, dataBlocks[section].body.GetBytes()); // bodyを暗号化 + + // (データ本体の後に不正データ挿入) + if (insertPos >= REAR_BANNER && insertPos <= REAR_SUB_BANNER) + { + if (section == insertPos - REAR_BANNER) + { + encryptedBlock = MergeByteArray(encryptedBlock, impData); + } + } + + if (byteHash != null) + { + byte[] buff = Utility.GetSha256(encryptedBlock); // 平文からSHA256ハッシュ算出 + buff.CopyTo(byteHash, 0); + byteMac = Utility.GetAesCmac(byteHash, prop.macKeyData); // SHA256ハッシュからMACを算出 + } + + encryptedBlock = Utility.EncryptBody(encryptedBlock, prop.keyData, dataBlocks[section].iv); // データ本体を暗号化 + encryptedBlock = MergeByteArray(encryptedBlock, byteMac); // MACを結合 + encryptedBlock = MergeByteArray(encryptedBlock, dataBlocks[section].iv); // IVを結合 + + // (データブロックの後に不正データ挿入) + if (section == SECTION_SUB_BANNER && insertPos == REAR_DATA) + { + encryptedBlock = MergeByteArray(encryptedBlock, impData); + } + + return encryptedBlock; + } + + /// + /// 各ブロックを暗号化した後、1つの byte 列に結合します。 + /// + /// 暗号化するデータ + /// バックアップデータに関するインスタンス + /// 不正データ + /// 不正データを挿入する位置 + /// ハッシュセット更新の有無 + /// 全てのBlockを暗号化し、連結したbyte列 + static byte[] MergeEncryptBody(Blocks dataBlocks, Properties prop, byte[] impData, int insertPos, int chgMacHash) + { + byte[] outData = new byte[0]; + byte[][] encryptedBlocks = new byte[BLOCK_NUM][]; + + byte[][] byteHash = new byte[BLOCK_NUM][]; + byte[][] byteMac = new byte[BLOCK_NUM][]; + + //---------------------- + // 各ブロックを暗号化 + // ( MAC & HASH SET更新する場合 ) + if (chgMacHash == CHG_MAC_AND_HASHSET) + { + for (int i = 0; i < BLOCK_NUM; i++) // 署名部以外を暗号化&byte列に結合 + { + byteHash[i] = new byte[HASH_SIZE]; + if (i != SECTION_SIGNATURE) + { + if (dataBlocks[i].body != null) + { + encryptedBlocks[i] = EncryptBlock(dataBlocks, i, prop, impData, insertPos, byteMac[i], byteHash[i]); // ブロックを暗号化&結合 + ChangeHashSet(dataBlocks, byteHash[i], i); // ハッシュセットを更新 + } + else + { + encryptedBlocks[i] = null; + } + } + } + // 最後に署名部を暗号化&byte列に結合 + byteHash[SECTION_SIGNATURE] = Utility.GetSha256(dataBlocks[SECTION_SIGNATURE].body.GetBytes()); // 平文からSHA256ハッシュ算出 + byteMac[SECTION_SIGNATURE] = Utility.GetAesCmac(byteHash[SECTION_SIGNATURE], prop.macKeyData); // SHA256ハッシュからMACを算出 + encryptedBlocks[SECTION_SIGNATURE] = EncryptBlock(dataBlocks, SECTION_SIGNATURE, prop, impData, insertPos, byteMac[SECTION_SIGNATURE]); + } + + // ( MAC & HASH SET更新しない場合 ) + else + { + for (int i = 0; i < BLOCK_NUM; i++) + { + if (dataBlocks[i].body != null) + { + encryptedBlocks[i] = EncryptBlock(dataBlocks, i, prop, impData, insertPos, dataBlocks[i].mac); // ブロックを暗号化&結合 + } + else + { + encryptedBlocks[i] = null; + } + } + } + + //---------------------- + // 暗号化した各ブロックを結合 + for (int i = 0; i < BLOCK_NUM; i++) + { + if (encryptedBlocks[i] != null) + { + outData = MergeByteArray(outData, encryptedBlocks[i]); + } + } + return outData; + } + + // static void FalsifyingData(int improperNo, Properties prop, byte[] improperData) + //------------------------------------------------------------ + // パターン番号に応じた改ざんを実行 + // [in] int improperNo : 改ざんパターン番号 + // [in] Properties prop : バックアップデータに関するインスタンス + // [in] byte[] improperData : 改ざんに使用する不正データ + //------------------------------------------------------------ + /// + /// パターン番号に応じた改ざんを実行 + /// + /// + /// + /// + static void FalsifyingData(int improperNo, Properties prop, byte[] improperData) + { + if (MIN_OF_CAT100 <= improperNo && improperNo <= MAX_OF_CAT100) + { + FalsifyingDataCategory1xx(improperNo, prop, improperData); + } + else if (MIN_OF_CAT200 <= improperNo && improperNo <= MAX_OF_CAT200) + { + FalsifyingDataCategory2xx(improperNo, prop, improperData); + } + else if (MIN_OF_CAT300 <= improperNo && improperNo <= MAX_OF_CAT300) + { + FalsifyingDataCategory3xx(improperNo, prop, improperData); + } + else if (MIN_OF_CAT400 <= improperNo && improperNo <= MAX_OF_CAT400) + { + FalsifyingDataCategory4xx(improperNo, prop, improperData); + } + else if (MIN_OF_CAT500 <= improperNo && improperNo <= MAX_OF_CAT500) + { + FalsifyingDataCategory5xx(improperNo, prop, improperData); + } + else + { + FalsifyingDataCategory9xx(improperNo, prop, improperData); + } + } + + // static void SwitchFalsifyingPattern(int falsifyingType, Properties prop) + //------------------------------------------------------------ + // 作成する改ざんデータのパターンを決定。 + // [in] int falsifyingMode : 出力する改ざんデータパターン + // [in] Properties prop : バックアップデータに関するインスタンス + //------------------------------------------------------------ + + /// + /// + /// + /// + /// + static void SwitchFalsifyingPattern(int falsifyingMode, Properties prop) + { + // 改ざんに使用する不正なデータ作成 + byte[] improperData = CreateImproperData(IMPROPER_DATA_SIZE); + + switch (falsifyingMode) + { + case MODE_ALL: // 全パターン + Console.WriteLine(" Falsifying \"all pattern\"."); + for (int i = 0; i < NUM_OF_PATTERN.GetLength(0); i++) + { + for (int j = NUM_OF_PATTERN[i, 0]; j <= NUM_OF_PATTERN[i, 1]; j++) + { + FalsifyingData(j, prop, improperData); + Console.WriteLine(" Complete falsifying No.{0}.", j); + } + Console.WriteLine(" Complete falsifying Cat.{0}.\n", NUM_OF_PATTERN[i, 0]); + } + break; + + case MODE_CAT100: // 1xx系列全て + Console.WriteLine(" Falsifying category No.{0}.", NUM_OF_PATTERN[MODE_CAT100 - 1, 0]); + for (int i = 100; i <= MAX_OF_CAT100; i++) + { + FalsifyingData(i, prop, improperData); + Console.WriteLine(" Complete falsifying No.{0}.", i); + } + Console.WriteLine(" Complete falsifying Cat.{0}.\n", NUM_OF_PATTERN[MODE_CAT100 - 1, 0]); + break; + + case MODE_CAT200: // 2xx系列全て + Console.WriteLine(" Falsifying category No.{0}.", NUM_OF_PATTERN[MODE_CAT200 - 1, 0]); + for (int i = 200; i <= MAX_OF_CAT200; i++) + { + FalsifyingData(i, prop, improperData); + Console.WriteLine(" Complete falsifying No.{0}.", i); + } + Console.WriteLine(" Complete falsifying Cat.{0}.\n", NUM_OF_PATTERN[MODE_CAT200 - 1, 0]); + break; + + case MODE_CAT300: // 3xx系列全て + Console.WriteLine(" Falsifying category No.{0}.", NUM_OF_PATTERN[MODE_CAT300 - 1, 0]); + for (int i = 300; i <= MAX_OF_CAT300; i++) + { + FalsifyingData(i, prop, improperData); + Console.WriteLine(" Complete falsifying No.{0}.", i); + } + Console.WriteLine(" Complete falsifying Cat.{0}.\n", NUM_OF_PATTERN[MODE_CAT300 - 1, 0]); + break; + + case MODE_CAT400: // 4xx系列全て + Console.WriteLine(" Falsifying category No.{0}.", NUM_OF_PATTERN[MODE_CAT400 - 1, 0]); + for (int i = 400; i <= MAX_OF_CAT400; i++) + { + FalsifyingData(i, prop, improperData); + Console.WriteLine(" Complete falsifying No.{0}.", i); + } + Console.WriteLine(" Complete falsifying Cat.{0}.\n", NUM_OF_PATTERN[MODE_CAT400 - 1, 0]); + break; + + case MODE_CAT500: // 5xx系列全て + Console.WriteLine(" Falsifying category No.{0}.", NUM_OF_PATTERN[MODE_CAT500 - 1, 0]); + for (int i = 500; i <= MAX_OF_CAT500; i++) + { + FalsifyingData(i, prop, improperData); + Console.WriteLine(" Complete falsifying No.{0}.", i); + } + Console.WriteLine(" Complete falsifying Cat.{0}.\n", NUM_OF_PATTERN[MODE_CAT500 - 1, 0]); + break; + + default: // 1パターンのみを個別指定 + Console.WriteLine(" Falsifying pattern No.{0}.", falsifyingMode); + FalsifyingData(falsifyingMode, prop, improperData); + Console.WriteLine(" Complete falsifying No.{0}.\n", falsifyingMode); + break; + } + } +} +} diff --git a/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj b/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj index c4dd1f8..23cf94b 100644 --- a/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj +++ b/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj @@ -49,6 +49,7 @@ +