📄 aescryptworkerthreads.cpp
字号:
result_code = in_buffered_file.ReadFile(buffer,
n,
&bytes_read);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
// XOR plain text block with previous encrypted
// output (i.e., use CBC)
for(i=0; i<16; i++)
{
buffer[i] ^= IV[i];
}
// Encrypt the contents of the buffer
aes_encrypt(&aes_ctx, buffer, buffer);
// Concatenate the "text" as we compute the HMAC
sha256_update(&sha_ctx, buffer, 16);
// Write the encrypted block
result_code = out_buffered_file.WriteFile(
buffer,
16,
&bytes_written);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to write to ") +
out_file,
result_code);
}
// Update the IV (CBC mode)
memcpy(IV, buffer, 16);
// Update the UI when more than 250ms has passed
// or when there is no more data to read or
// when the next 1 percent of the file has been
// processed
current_percent =
(file_size.QuadPart - bytes_left) *
100 / file_size.QuadPart;
if ((clock() - last_clock_time >
(CLOCKS_PER_SEC / 4)) ||
(bytes_left == 0) ||
(current_percent > last_percent))
{
// Update the progress bar
dlg.SendDlgItemMessage(
IDC_PROGRESSBAR,
PBM_SETPOS,
(WPARAM) current_percent,
0);
dlg.UpdateWindow();
DoMessageLoop();
if (dlg.abort_processing == true)
{
error_abort = true;
break;
}
last_clock_time = clock();
last_percent = current_percent;
}
}
if (error_abort == false)
{
// Write the HMAC
sha256_finish(&sha_ctx, digest);
sha256_starts(&sha_ctx);
sha256_update(&sha_ctx, opad, 64);
sha256_update(&sha_ctx, digest, 32);
sha256_finish(&sha_ctx, digest);
buffer[0] = (char) (file_size.LowPart & 0x0F);
result_code = out_buffered_file.WriteFile(
buffer,
1,
&bytes_written);
if (result_code == ERROR_SUCCESS)
{
result_code = out_buffered_file.WriteFile(
digest,
32,
&bytes_written);
}
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to write to ") +
out_file,
result_code);
}
}
}
catch(SystemErrorException e)
{
::ReportError(e.Message,e.Reason);
error_abort = true;
}
in_buffered_file.CloseFile();
out_buffered_file.CloseFile();
// We will attempt to cleanup, but we don't care if this
// really works or not...
if (error_abort == true)
{
DeleteFile(out_file.c_str());
error_abort = true;
}
}
}
// Remove the filename from the list
file_list->pop_front();
}
// For security reasons, erase the password
memset(passwd, 0, sizeof(TCHAR) * MAX_PASSWD_LEN);
// We processed the files, so we must have properly allocated hProv.
// Now, release it.
if (file_list->empty())
{
CryptReleaseContext(hProv, 0);
}
// Destroy the progress window
dlg.DestroyWindow();
}
/*
* DecryptFiles
*
* This function is called by the worker thread to decrypt a list of files.
*/
void AESCryptWorkerThreads::DecryptFiles(
StringList *file_list,
TCHAR *passwd)
{
aes_context aes_ctx;
sha256_context sha_ctx;
std::basic_string<TCHAR> in_file;
TCHAR out_file[MAX_PATH+1];
TCHAR *p;
BufferedFile in_buffered_file,
out_buffered_file;
DWORD result_code;
unsigned char IV[16];
unsigned char buffer[32], buffer2[32];
unsigned char iv_key[48];
unsigned char digest[32];
LARGE_INTEGER file_size; // 64-bit integer structure
ULONGLONG bytes_left;
int last_block_size;
bool last_block_size_read;
int i, j, n;
DWORD bytes_written, bytes_read;
unsigned char ipad[64];
unsigned char opad[64];
bool error_abort = false;
ProgressDialog dlg;
unsigned version;
unsigned footprint;
clock_t last_clock_time;
ULONGLONG last_percent, current_percent;
// Passing a zero instructs the dialog to display
// "Decrypting..."
dlg.Create(NULL,0);
// Walk through the list of files decrypting each
while(!file_list->empty() && !error_abort)
{
// Get the filename
in_file = file_list->front();
_tcscpy_s(out_file, MAX_PATH, in_file.c_str());
i = (int) _tcslen(out_file);
if (i < 5)
{
::ReportError( _T("Invalid input file name: ") + in_file,
0);
error_abort = true;
}
// Reset the progress bar (default range is 0..100)
dlg.SendDlgItemMessage( IDC_PROGRESSBAR,
PBM_SETPOS,
0,
0);
// Display the file name
dlg.SetDlgItemText( IDC_FILENAME,
in_file.c_str());
// Make sure the window is visible
dlg.ShowWindow(SW_SHOWNORMAL);
dlg.UpdateWindow();
DoMessageLoop();
// Remove the .aes extension (we hope ... gulp)
p = out_file + i - 4;
*p = _T('\0');
if (error_abort == false)
{
result_code = in_buffered_file.OpenFile(in_file.c_str(),
false,
OPEN_EXISTING);
if (result_code != ERROR_SUCCESS)
{
::ReportError( _T("Unable to open input file ") + in_file,
result_code);
error_abort = true;
}
}
if (error_abort == false)
{
result_code = out_buffered_file.OpenFile( out_file,
true,
CREATE_NEW);
if (result_code != ERROR_SUCCESS)
{
std::basic_string<TCHAR> message;
// Close the input file
in_buffered_file.CloseFile();
message = _T("Unable to open output file ");
message += out_file;
::ReportError(message, result_code);
error_abort = true;
}
else
{
try
{
// Determine the file size
result_code = in_buffered_file.FileSize(&file_size);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to determine file size of ") +
in_file,
result_code);
}
if (file_size.QuadPart < FOOTPRINT_V0)
{
throw SystemErrorException(
_T("Invalid input file ") +
in_file + _T("\n File too short"),
0);
}
// Read the file header
result_code = in_buffered_file.ReadFile(buffer,
5,
&bytes_read);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
if (buffer[0] != 'A' || buffer[1] != 'E' ||
buffer[2] != 'S')
{
throw SystemErrorException(
_T("Invalid input file ") +
in_file + _T("\n Invalid signature"),
0);
}
version = (unsigned) buffer[3];
if (version > 1)
{
throw SystemErrorException(
_T("Invalid input file ") +
in_file + _T("\n Unsupported version"),
0);
}
// How many bytes are left in the message
// (excludes header and HMAC)
if (version == 0)
{
bytes_left = file_size.QuadPart - FOOTPRINT_V0;
// Determine the number of octets in the last data block
last_block_size = (int) buffer[4] & 0x0F;
footprint = FOOTPRINT_V0;
}
else // Must be a V1 file
{
if (file_size.QuadPart < FOOTPRINT_V1)
{
throw SystemErrorException(
_T("Invalid input file ") +
in_file + _T("\n File too short"),
0);
}
bytes_left = file_size.QuadPart - FOOTPRINT_V1;
footprint = FOOTPRINT_V1;
}
// The message must be a multiple of 16 octets
if (bytes_left & 0x0F)
{
throw SystemErrorException(
_T("Invalid input file ") +
in_file + _T("\n Message length invalid"),
0);
}
// Read the IV
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -