📄 aescryptworkerthreads.cpp
字号:
result_code = in_buffered_file.ReadFile(IV,
16,
&bytes_read);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
// Hash the IV and password 8192 times
memset(digest, 0, 32);
memcpy(digest, IV, 16);
for(i=0; i<8192; i++)
{
sha256_starts( &sha_ctx);
sha256_update( &sha_ctx, digest, 32);
sha256_update( &sha_ctx,
(unsigned char*)passwd,
// Unicode means the bytes are twice
// the string length.
(unsigned long)
_tcsnlen(passwd, MAX_PASSWD_LEN+1)*
sizeof(TCHAR));
sha256_finish( &sha_ctx,
digest);
}
// Because the aes_set_key routine is not thread safe,
// protect it with a critical section.
EnterCriticalSection(&Critical_Section);
aes_set_key(&aes_ctx, digest, 256);
LeaveCriticalSection(&Critical_Section);
// Set the ipad and opad arrays with values as
// per RFC 2104 (HMAC). HMAC is defined as
// H(K XOR opad, H(K XOR ipad, text))
memset(ipad, 0x36, 64);
memset(opad, 0x5C, 64);
for(i=0; i<32; i++)
{
ipad[i] ^= digest[i];
opad[i] ^= digest[i];
}
sha256_starts(&sha_ctx);
sha256_update(&sha_ctx, ipad, 64);
// If this is a version 1 file, then read the IV and key
// for decrypting the bulk of the file.
if (version == 1)
{
for(i=0; i<48; i+=16)
{
result_code = in_buffered_file.ReadFile(buffer,
16,
&bytes_read);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
memcpy(buffer2, buffer, 16);
sha256_update(&sha_ctx, buffer, 16);
aes_decrypt(&aes_ctx, buffer, buffer);
// XOR plain text block with previous encrypted
// output (i.e., use CBC)
for(j=0; j<16; j++)
{
iv_key[i+j] = (buffer[j] ^ IV[j]);
}
// Update the IV (CBC mode)
memcpy(IV, buffer2, 16);
}
// Verify that the HMAC is correct
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);
result_code = in_buffered_file.ReadFile(buffer,
32,
&bytes_read);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
if (memcmp(digest, buffer, 32))
{
throw SystemErrorException(
_T("Error in file ") +
in_file +
_T("\nMessage has been altered or password is incorrect"),
0);
}
// Re-load the IV and encryption key with the IV and
// key to now encrypt the datafile. Also, reset the HMAC
// computation.
memcpy(IV, iv_key, 16);
// Because the aes_set_key routine is not thread safe,
// protect it with a critical section.
EnterCriticalSection(&Critical_Section);
aes_set_key(&aes_ctx, iv_key+16, 256);
LeaveCriticalSection(&Critical_Section);
// Set the ipad and opad arrays with values as
// per RFC 2104 (HMAC). HMAC is defined as
// H(K XOR opad, H(K XOR ipad, text))
memset(ipad, 0x36, 64);
memset(opad, 0x5C, 64);
for(i=0; i<32; i++)
{
ipad[i] ^= iv_key[i+16];
opad[i] ^= iv_key[i+16];
}
// Wipe the IV and encryption mey from memory
memset(iv_key, 0, 48);
sha256_starts(&sha_ctx);
sha256_update(&sha_ctx, ipad, 64);
}
last_clock_time = clock();
current_percent = 0;
last_block_size_read = false;
while(bytes_left > 0)
{
bytes_left -= 16;
result_code = in_buffered_file.ReadFile(buffer,
16,
&bytes_read);
// If we're processing a version 1 file and we reach
// the end of the file, then let's read the file size
// modulo octet.
if (bytes_left == 0 && version == 1 &&
result_code == ERROR_SUCCESS)
{
result_code = in_buffered_file.ReadFile(buffer2,
1,
&bytes_read);
// Determine the number of octets in the last
// data block
last_block_size = (int) buffer2[0] & 0x0F;
last_block_size_read = true;
}
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
memcpy(buffer2, buffer, 16);
sha256_update(&sha_ctx, buffer, 16);
aes_decrypt(&aes_ctx, buffer, buffer);
// XOR plain text block with previous encrypted
// output (i.e., use CBC)
for(i=0; i<16; i++)
{
buffer[i] ^= IV[i];
}
// Update the IV (CBC mode)
memcpy(IV, buffer2, 16);
// If this is the final block, then we may
// write less than 16 octets
n = ((bytes_left > 0) ||
(last_block_size == 0)) ? 16 : last_block_size;
// Write the decrypted block
result_code = out_buffered_file.WriteFile(
buffer,
n,
&bytes_written);
if (result_code != ERROR_SUCCESS)
{
std::basic_string<TCHAR> message;
message = _T("Unable to write to ");
message += out_file;
throw SystemErrorException(message, result_code);
}
// 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 - footprint) *
100 / (file_size.QuadPart - footprint);
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)
{
if (last_block_size_read == false && version == 1)
{
result_code = in_buffered_file.ReadFile(buffer2,
1,
&bytes_read);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
// Determine the number of octets in the last
// data block
last_block_size = (int) buffer2[0] & 0x0F;
}
// Verify that the HMAC is correct
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);
result_code = in_buffered_file.ReadFile(buffer,
32,
&bytes_read);
if (result_code != ERROR_SUCCESS)
{
throw SystemErrorException(
_T("Unable to read ") +
in_file,
result_code);
}
if (memcmp(digest, buffer, 32))
{
if (version == 0)
{
throw SystemErrorException(
_T("Error in file ") +
in_file +
_T("\nMessage has been altered or password is incorrect"),
0);
}
else
{
throw SystemErrorException(
_T("Error in file ") +
in_file +
_T("\nMessage has been altered and should not be trusted."),
0);
}
}
}
}
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);
}
}
}
// Remove the filename from the list
file_list->pop_front();
}
// For security reasons, erase the password
memset(passwd, 0, sizeof(TCHAR) * MAX_PASSWD_LEN);
// Destroy the progress window
dlg.DestroyWindow();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -