From 1ade5026350fa99d716b44ccc25859a4f0cf0d72 Mon Sep 17 00:00:00 2001 From: N2614 Date: Tue, 15 Mar 2011 11:07:27 +0000 Subject: [PATCH] =?UTF-8?q?=E3=82=BD=E3=83=95=E3=83=88AES=20CTR=E3=83=A2?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=8C16=E3=83=90=E3=82=A4=E3=83=88?= =?UTF-8?q?=E3=83=96=E3=83=AD=E3=83=83=E3=82=AF=E3=83=A2=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=AE=E3=81=BF=E3=81=AE=E3=81=9F=E3=82=81PKCS#5=E3=81=A7?= =?UTF-8?q?=E3=83=91=E3=83=87=E3=82=A3=E3=83=B3=E3=82=B0=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20SD=E5=87=BA=E5=8A=9B=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=AE=E5=85=88=E9=A0=AD=E3=81=AB?= =?UTF-8?q?=E3=83=98=E3=83=83=E3=83=80=E3=82=92=E3=81=A4=E3=81=91=E3=81=A6?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=B5=E3=82=A4=E3=82=BA?= =?UTF-8?q?=E3=82=92=E5=8F=96=E5=BE=97=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=20NAND=E6=9B=B8=E3=81=8D=E8=BE=BC=E3=81=BF?= =?UTF-8?q?=E6=99=82=E3=81=AE=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=B5?= =?UTF-8?q?=E3=82=A4=E3=82=BA=E3=82=92=E6=AD=A3=E3=81=97=E3=81=8F=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=20CopyDi?= =?UTF-8?q?rectory=E3=81=AB=E3=81=AF16=E3=83=90=E3=82=A4=E3=83=88=E3=82=A2?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=B3=E3=81=97=E3=81=9F=E3=83=90=E3=83=83?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=92=E6=B8=A1=E3=81=99=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@140 385bec56-5757-e545-9c3a-d8741f4650f1 --- .../ConsoleBackup/Exporter.cpp | 4 +- .../ConsoleRestore/Importer.cpp | 4 +- .../ConsoleDataMigration/common/Aes_define.h | 6 +- .../common/FileTransfer.cpp | 252 +++++++++++------- .../common/common_Types.h | 7 + 5 files changed, 173 insertions(+), 100 deletions(-) diff --git a/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp b/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp index ab63490..766650e 100644 --- a/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp +++ b/trunk/ConsoleDataMigration/ConsoleBackup/Exporter.cpp @@ -326,7 +326,7 @@ void WriteTwlData(enum common::TWL_PATH_INDEX path) // 進捗表示用 common::InitializeTransferProgress(fileSize); - void* buf = common::HeapManager::GetHeap()->Allocate(bufSize); + void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE); if (buf != NULL) { wchar_t archiveName[256]; @@ -408,7 +408,7 @@ void ExportThreadFunc() size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize(); NN_LOG("AllocatableSize = %d\n", bufSize); - void* buf = common::HeapManager::GetHeap()->Allocate(bufSize); + void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE); if (buf != NULL) { diff --git a/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp b/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp index fb0df47..10c5e58 100644 --- a/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp +++ b/trunk/ConsoleDataMigration/ConsoleRestore/Importer.cpp @@ -664,7 +664,7 @@ void ImportThreadFunc() size_t bufSize = common::HeapManager::GetHeap()->GetAllocatableSize(); NN_LOG("AllocatableSize = %d\n", bufSize); - void* buf = common::HeapManager::GetHeap()->Allocate(bufSize); + void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE); if (buf != NULL) { @@ -1316,7 +1316,7 @@ void ImportTwlData(enum common::TWL_PATH_INDEX path) NN_LOG("File Size = %d\n", fileSize); - void* buf = common::HeapManager::GetHeap()->Allocate(bufSize); + void* buf = common::HeapManager::GetHeap()->Allocate(bufSize, AES_BLOCK_SIZE); if (buf != NULL) { wchar_t archiveName[256]; diff --git a/trunk/ConsoleDataMigration/common/Aes_define.h b/trunk/ConsoleDataMigration/common/Aes_define.h index a817305..a31eb56 100644 --- a/trunk/ConsoleDataMigration/common/Aes_define.h +++ b/trunk/ConsoleDataMigration/common/Aes_define.h @@ -20,7 +20,7 @@ namespace common { - const bit8 key[AES_KEY_SIZE] = + const bit8 key[AES_KEY_SIZE] NN_ATTRIBUTE_ALIGN(4) = { 0x81, 0x35, 0xc6, 0x54, 0x19, 0x1a, 0x47, 0x2a, 0x6b, 0x78, 0xbe, 0x25, 0x90, 0xf6, 0xee, 0x74 @@ -32,13 +32,11 @@ namespace common 0x04, 0x21, 0x9c, 0x5e, 0x33, 0x8c, 0x3d, 0xaa }; - const bit8 iv[AES_BLOCK_SIZE] = + const bit8 iv[AES_BLOCK_SIZE] NN_ATTRIBUTE_ALIGN(4) = { 0xdf, 0x0f, 0xf9, 0x1b, 0x34, 0x47, 0x70, 0x7f, 0x7d, 0x06, 0x85, 0xe6, 0xe7, 0xb6, 0x4e, 0xe9 }; - - } #endif /* AES_DEFINE_H_ */ diff --git a/trunk/ConsoleDataMigration/common/FileTransfer.cpp b/trunk/ConsoleDataMigration/common/FileTransfer.cpp index 091ea9a..7ce23f6 100644 --- a/trunk/ConsoleDataMigration/common/FileTransfer.cpp +++ b/trunk/ConsoleDataMigration/common/FileTransfer.cpp @@ -23,6 +23,7 @@ #include "Aes_define.h" #include "FileTransfer.h" #include "CommonLogger.h" +#include "common_Types.h" namespace common { @@ -173,6 +174,7 @@ bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf nn::fs::FileInputStream from_file; nn::fs::FileOutputStream to_file; s64 filesize; + s64 fileSizeWithoutHeaderAndFooter; s32 readsize; s32 writesize; @@ -209,126 +211,192 @@ bool CopyDirectory(const wchar_t * from_path, const wchar_t * to_path, void* buf } } - // 書き込み対象ファイル作成 - result = nn::fs::TryCreateFile(target_to.str().c_str(), filesize); - result = to_file.TryInitialize(target_to.str().c_str(), false); - if (result.IsFailure()) + nn::crypto::SwAesCtrContext swAesCtrContext; + swAesCtrContext.Initialize(iv, common::key, sizeof(key)); + + size_t totalReadSize = 0; + nn::crypto::Sha256Context context; + context.Initialize(); + + // ファイルサイズをヘッダに書いておく + if (encode) { - nn::dbg::PrintResult(result); - ret_value = false; + // 書き込み対象ファイル作成 + result = nn::fs::TryCreateFile(target_to.str().c_str(), filesize); + result = to_file.TryInitialize(target_to.str().c_str(), false); + if (result.IsFailure()) + { + nn::dbg::PrintResult(result); + ret_value = false; + } + + BackupDataHeader header; + BackupDataHeader enc; + header.size = filesize; + result = swAesCtrContext.Encrypt(&enc, &header, sizeof(header)); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + context.Update(&enc, sizeof(enc)); + s32 writeSize; + result = to_file.TryWrite(&writeSize, &enc, sizeof(enc), false); + if (result.IsFailure()) + { + ret_value = false; + continue; + } } else { - nn::crypto::SwAesCtrContext swAesCtrContest; - swAesCtrContest.Initialize(iv, common::key, sizeof(key)); - - size_t totalReadSize = 0; - nn::crypto::Sha256Context context; - context.Initialize(); - - while (1) + // ヘッダを読む + // ハッシュの計算は終わっているので復号化のみ + BackupDataHeader header; + BackupDataHeader dec; + s32 readSize; + result = from_file.TryRead(&readSize, &header, sizeof(header)); + if (result.IsFailure()) { - // バッファの後半半分を暗号・復号用に使う - result = from_file.TryRead(&readsize, buf, bufSize / 2); - totalReadSize += readsize; + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + ret_value = false; + continue; + } + s_FinishedFileSize += sizeof(header); + swAesCtrContext.Decrypt(&dec, &header, sizeof(header)); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + fileSizeWithoutHeaderAndFooter = dec.size; - if (result.IsFailure()) + // 書き込み対象ファイル作成 + result = nn::fs::TryCreateFile(target_to.str().c_str(), fileSizeWithoutHeaderAndFooter); + result = to_file.TryInitialize(target_to.str().c_str(), false); + if (result.IsFailure()) + { + nn::dbg::PrintResult(result); + ret_value = false; + } + } + + while (1) + { + // バッファの後半半分を暗号・復号用に使う + result = from_file.TryRead(&readsize, buf, bufSize / 2); + totalReadSize += readsize; + + if (result.IsFailure()) + { + nn::dbg::PrintResult(result); + ret_value = false; + break; + } + else + { + if (readsize == 0) { - nn::dbg::PrintResult(result); - ret_value = false; + if (encode) + { + NN_LOG("Add CMAC %ls\n", target_from.str().c_str()); + // SHA256を計算してCMACを付加する + bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE]; + context.GetHash(sha256Hash); + + bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE]; + result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, + nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + result = to_file.TryWrite(&writesize, cmac, sizeof(cmac)); + if (result.IsFailure()) + { + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + ret_value = false; + } + } + + result = to_file.TryFlush(); + if (result.IsFailure()) + { + nn::dbg::PrintResult(result); + ret_value = false; + } break; } else { - if (readsize == 0) + if (encode) { - if(encode) + NN_LOG("EncryptSize = %d\n", readsize); + + u8 paddingSize = 0; + // 最後の書き込み時にはPKCS5でパディングする + if (readsize < bufSize / 2) { - NN_LOG("Add CMAC %ls\n", target_from.str().c_str()); - // SHA256を計算してCMACを付加する - bit8 sha256Hash[nn::crypto::Sha256Context::HASH_SIZE]; - context.GetHash(sha256Hash); - - bit8 cmac[nn::crypto::AES_CMAC_MAC_SIZE]; - result = nn::crypto::CalculateAesCmacSw(cmac, sha256Hash, nn::crypto::Sha256Context::HASH_SIZE, common::cmacKey); - COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - - result = to_file.TryWrite(&writesize, cmac, sizeof(cmac)); - if(result.IsFailure()) + if ((readsize % AES_BLOCK_SIZE) != 0) { - COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - ret_value = false; + paddingSize = AES_BLOCK_SIZE - readsize % AES_BLOCK_SIZE; + std::memset(reinterpret_cast (buf) + readsize, paddingSize, + paddingSize); + readsize += paddingSize; } } - result = to_file.TryFlush(); - if (result.IsFailure()) - { - nn::dbg::PrintResult(result); - ret_value = false; - } - break; + // 暗号化後SHA256を計算しつつ書き込み + result = swAesCtrContext.Encrypt(reinterpret_cast (buf) + bufSize / 2, buf, + readsize); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + context.Update(reinterpret_cast (buf) + bufSize / 2, readsize); + + result = to_file.TryWrite(&writesize, reinterpret_cast (buf) + bufSize / 2, + readsize, false); + + // 事前計算したファイルサイズに一致させるためパディング分減算 + readsize -= paddingSize; + + s_FinishedFileSize += readsize; + s_Progress = s_FinishedFileSize * 100 / s_TotalFileSize; + NN_LOG("finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress); } else { - if (encode) - { - // 暗号化後SHA256を計算しつつ書き込み - result = swAesCtrContest.Encrypt(reinterpret_cast (buf) + bufSize / 2, - buf, readsize); - COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - context.Update(reinterpret_cast (buf) + bufSize / 2, readsize); + // ハッシュ検証は通っているので復号化しつつ書き込み + // パディング以降は書き込まないよう書き込みサイズを変更する - result = to_file.TryWrite(&writesize, reinterpret_cast(buf) + bufSize / 2 , readsize, false); - s_FinishedFileSize += readsize; - s_Progress = s_FinishedFileSize * 100/ s_TotalFileSize; - NN_LOG("finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress); + NN_LOG("DecryptSize = %d\n", readsize); + result = swAesCtrContext.Decrypt(reinterpret_cast (buf) + bufSize / 2, buf, + readsize); + COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); + + // パディングまで読んだかどうか + bool readDone = false; + // パディングまで読んでいたら書き込みサイズを減らす + if (fileSizeWithoutHeaderAndFooter < totalReadSize) + { + readsize -= totalReadSize - fileSizeWithoutHeaderAndFooter; + readDone = true; + s_FinishedFileSize += totalReadSize - fileSizeWithoutHeaderAndFooter; } - else - { - // ハッシュ検証は通っているので復号化しつつ書き込み - // ハッシュ部分は書き込まないよう書き込みサイズを取得する - // ハッシュ部分まで読んだかどうか - bool readDone = false; - // ハッシュ部分まで読んでいたら書き込みサイズを減らす - size_t fileSizeWithoutCmac = filesize - nn::crypto::AES_CMAC_MAC_SIZE; - if (fileSizeWithoutCmac < totalReadSize) + result = to_file.TryWrite(&writesize, reinterpret_cast (buf) + bufSize / 2, + readsize, false); + s_FinishedFileSize += readsize; + s_Progress = s_FinishedFileSize * 100 / s_TotalFileSize; + NN_LOG("finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress); + + // 読みきったので次のファイルへ + if (readDone) + { + result = to_file.TryFlush(); + if (result.IsFailure()) { - readsize -= totalReadSize - fileSizeWithoutCmac; - readDone = true; - s_FinishedFileSize += nn::crypto::AES_CMAC_MAC_SIZE; + ret_value = false; } - - result = swAesCtrContest.Decrypt(reinterpret_cast(buf) + bufSize / 2, buf, readsize); COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - - result = to_file.TryWrite(&writesize, reinterpret_cast(buf) + bufSize / 2 , readsize, false); - s_FinishedFileSize += readsize; - s_Progress = s_FinishedFileSize * 100/ s_TotalFileSize; - NN_LOG("finish = %lld, total = %lld, progress = %lld\n", s_FinishedFileSize, s_TotalFileSize, s_Progress); - - // 読みきったので次のファイルへ - if (readDone) - { - result = to_file.TryFlush(); - if (result.IsFailure()) - { - ret_value = false; - } - COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result); - break; - } + break; } - - - if (result.IsFailure()) - { - nn::dbg::PrintResult(result); - ret_value = false; - } - } + + if (result.IsFailure()) + { + nn::dbg::PrintResult(result); + ret_value = false; + } + } } } diff --git a/trunk/ConsoleDataMigration/common/common_Types.h b/trunk/ConsoleDataMigration/common/common_Types.h index 8424837..2a354a3 100644 --- a/trunk/ConsoleDataMigration/common/common_Types.h +++ b/trunk/ConsoleDataMigration/common/common_Types.h @@ -80,6 +80,13 @@ const nn::ProgramId cNupVerId[] = nn::pl::CTR::SHAREDDATA_TITLEID_NUP_VERSION_EU, }; +struct BackupDataHeader +{ + s64 size; // パディングを含まないファイルサイズ + NN_PADDING4; + NN_PADDING4; +}; + } #endif /* COMMON_TYPES_H_ */