VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Main/Forms/WaitDialog.h
blob: b12ad028f8c494b2cfba2f5b7a15ca47cc11b497 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
 Copyright (c) 2014 IDRIX. All rights reserved.

 Governed by the VeraCrypt License the full text of which is contained in
 the file License.txt included in VeraCrypt binary and source code distribution
 packages.
*/

#ifndef TC_HEADER_Main_Forms_WaitDialog
#define TC_HEADER_Main_Forms_WaitDialog

#include "Forms.h"
#include "Main/Main.h"
#include "Main/Application.h"
#include <wx/msgqueue.h>

namespace VeraCrypt
{

	DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED, -1);
	DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_WAITDIALOG_ADMIN_PASSWORD, -1);
	DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_WAITDIALOG_PIN, -1);
	DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_WAITDIALOG_SHOW_MSG, -1);
	
	class WaitDialog;



	class WaitThread : public wxThread
	{
	public:
		WaitThread(WaitDialog *handler, WaitThreadRoutine* pRoutine) : wxThread(wxTHREAD_DETACHED), m_pRoutine(pRoutine)
		{
			m_pHandler = handler;			
		}
		~WaitThread()
		{			
		}
		
	protected:
		virtual ExitCode Entry();
		WaitDialog *m_pHandler;
		WaitThreadRoutine* m_pRoutine;
	};

	class WaitDialog : public WaitDialogBase, public WaitThreadUI
	{
	public:
		WaitDialog (wxWindow *parent, const wxString& label, WaitThreadRoutine* pRoutine) 
			: WaitDialogBase(parent), WaitThreadUI(pRoutine), m_timer (this)
		{
			WaitStaticText->SetLabel (label);
			WaitProgessBar->Pulse();
			Layout();
			GetSizer()->Fit( this );
			Centre( wxBOTH );
			Connect( wxID_ANY, wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED, wxCommandEventHandler( WaitDialog::OnThreadCompletion ) );
			Connect( wxID_ANY, wxEVT_COMMAND_WAITDIALOG_ADMIN_PASSWORD, wxCommandEventHandler( WaitDialog::OnAdminPasswordRequest ) );
			Connect( wxID_ANY, wxEVT_COMMAND_WAITDIALOG_PIN, wxCommandEventHandler( WaitDialog::OnPinRequest ) );
			Connect( wxID_ANY, wxEVT_COMMAND_WAITDIALOG_SHOW_MSG, wxCommandEventHandler( WaitDialog::OnShowMsg ) );
			
			Connect( wxEVT_TIMER, wxTimerEventHandler( WaitDialog::OnProgressTimer ), NULL, this );
			m_thread = new WaitThread(this, pRoutine);
		}
		
		~WaitDialog()
		{
			Disconnect( wxEVT_TIMER, wxTimerEventHandler( WaitDialog::OnProgressTimer ));
			Disconnect( wxID_ANY, wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED, wxCommandEventHandler( WaitDialog::OnThreadCompletion ) );
			Disconnect( wxID_ANY, wxEVT_COMMAND_WAITDIALOG_ADMIN_PASSWORD, wxCommandEventHandler( WaitDialog::OnAdminPasswordRequest ) );
			Disconnect( wxID_ANY, wxEVT_COMMAND_WAITDIALOG_PIN, wxCommandEventHandler( WaitDialog::OnPinRequest ) );
			Disconnect( wxID_ANY, wxEVT_COMMAND_WAITDIALOG_SHOW_MSG, wxCommandEventHandler( WaitDialog::OnShowMsg ) );
		}

		virtual void OnWaitDialogInit( wxInitDialogEvent& event )
		{	
			m_thread->Run();
			m_timer.Start(100);
		}

		int GetCharWidth (wxWindow *window) const
		{
			int width;
			int height;
			window->GetTextExtent (L"a", &width, &height);

			if (width < 1)
				return 7;

			return width;
		}

		class ShowMessageParam
		{
		public:
			wxString m_message;
			wxString m_caption;
			long m_style;
			bool m_topMost;
			ShowMessageParam(const wxString &message, const wxString &caption,long style, bool topMost)
				: m_message(message), m_caption(caption), m_style(style), m_topMost(topMost)
			{}
		};

		int RequestShowMessage (const wxString &message, const wxString &caption,long style, bool topMost)
		{
			long lResult = -1;
			if (m_queue.IsOk())
			{
				wxString sResult;
				ShowMessageParam* pParam = new ShowMessageParam(message, caption, style, topMost);
				wxCommandEvent* pEvent = new wxCommandEvent( wxEVT_COMMAND_WAITDIALOG_SHOW_MSG,0);
				pEvent->SetClientData (pParam);
				wxQueueEvent (this, pEvent);
				m_queue.Receive (sResult);
				sResult.ToLong(&lResult);
			}	
			return (int) lResult;
		}

		void RequestAdminPassword (wxString& adminPassword)
		{
			if (m_queue.IsOk())
			{
				wxQueueEvent (this, new wxCommandEvent( wxEVT_COMMAND_WAITDIALOG_ADMIN_PASSWORD,0));
				if (wxMSGQUEUE_NO_ERROR != m_queue.Receive (adminPassword))
					adminPassword = wxT("");
			}
			else
				adminPassword = wxT("");
		}

		void RequestPin (wxString& pin)
		{
			if (m_queue.IsOk())
			{
				wxCommandEvent* pEvent = new wxCommandEvent( wxEVT_COMMAND_WAITDIALOG_PIN,0);
				pEvent->SetString (pin);
				wxQueueEvent (this, pEvent);
				if (wxMSGQUEUE_NO_ERROR != m_queue.Receive (pin))
					pin = wxT("");
			}
			else
				pin = wxT("");
		}
		
		// virtual void OnWaitDialogClose( wxCloseEvent& event ) { }
		void OnThreadCompletion(wxCommandEvent &)
		{
			m_queue.Clear();
			EndModal(0);
		}

		void OnAdminPasswordRequest(wxCommandEvent &)
		{

			wxPasswordEntryDialog dialog (this, _("Enter your user password or administrator password:"), _("Administrator privileges required"));
			if (dialog.ShowModal() != wxID_OK)
				m_queue.Post(wxT(""));
			else
				m_queue.Post(dialog.GetValue());
		}



		void OnPinRequest(wxCommandEvent &e)
		{

			wxPasswordEntryDialog dialog (this, wxString::Format (LangString["ENTER_TOKEN_PASSWORD"], e.GetString()), LangString["IDD_TOKEN_PASSWORD"]);
			dialog.SetSize (wxSize (GetCharWidth (&dialog) * 50, -1));

			if (dialog.ShowModal() != wxID_OK)
				m_queue.Post(wxT(""));
			else
				m_queue.Post(dialog.GetValue());
		}

		void OnShowMsg(wxCommandEvent &e)
		{
			ShowMessageParam* pParam = (ShowMessageParam*) e.GetClientData();
			if (pParam->m_topMost)
			{
				if (!IsActive())
					RequestUserAttention (wxUSER_ATTENTION_ERROR);

				pParam->m_style |= wxSTAY_ON_TOP;
			}

			int iResult = wxMessageBox (pParam->m_message, pParam->m_caption, pParam->m_style, this);
			delete pParam;		
			m_queue.Post(wxString::Format(wxT("%d"), iResult));
		}
		
		void OnProgressTimer(wxTimerEvent& event)
		{
			WaitProgessBar->Pulse();
		}

		virtual void Run(void) { ShowModal(); if (m_pRoutine->HasException()) ThrowException(m_pRoutine->m_pException); }

		void ThrowException(Exception* ex);

	protected:
		WaitThread* m_thread;
		wxTimer m_timer;
		wxMessageQueue<wxString> m_queue;
	};
}

#endif // TC_HEADER_Main_Forms_WaitDialog
DLL_EXPORT call %1 add esp,%2 %else call %1@%2 %endif %endmacro %macro do_exit 0-1 parms %ifdef DLL_EXPORT ret %1 %else ret %endif %endmacro %ifdef ENCRYPTION extern t_fn %define etab_0(x) [t_fn+4*x] %define etab_1(x) [t_fn+1024+4*x] %define etab_2(x) [t_fn+2048+4*x] %define etab_3(x) [t_fn+3072+4*x] %ifdef LAST_ROUND_TABLES extern t_fl %define eltab_0(x) [t_fl+4*x] %define eltab_1(x) [t_fl+1024+4*x] %define eltab_2(x) [t_fl+2048+4*x] %define eltab_3(x) [t_fl+3072+4*x] %else %define etab_b(x) byte [t_fn+3072+4*x] %endif ; ROUND FUNCTION. Build column[2] on ESI and column[3] on EDI that have the ; round keys pre-loaded. Build column[0] in EBP and column[1] in EBX. ; ; Input: ; ; EAX column[0] ; EBX column[1] ; ECX column[2] ; EDX column[3] ; ESI column key[round][2] ; EDI column key[round][3] ; EBP scratch ; ; Output: ; ; EBP column[0] unkeyed ; EBX column[1] unkeyed ; ESI column[2] keyed ; EDI column[3] keyed ; EAX scratch ; ECX scratch ; EDX scratch %macro rnd_fun 2 rol ebx,16 %1 esi, cl, 0, ebp %1 esi, dh, 1, ebp %1 esi, bh, 3, ebp %1 edi, dl, 0, ebp %1 edi, ah, 1, ebp %1 edi, bl, 2, ebp %2 ebp, al, 0, ebp shr ebx,16 and eax,0xffff0000 or eax,ebx shr edx,16 %1 ebp, ah, 1, ebx %1 ebp, dh, 3, ebx %2 ebx, dl, 2, ebx %1 ebx, ch, 1, edx %1 ebx, al, 0, edx shr eax,16 shr ecx,16 %1 ebp, cl, 2, edx %1 edi, ch, 3, edx %1 esi, al, 2, edx %1 ebx, ah, 3, edx %endmacro ; Basic MOV and XOR Operations for normal rounds %macro nr_xor 4 movzx %4,%2 xor %1,etab_%3(%4) %endmacro %macro nr_mov 4 movzx %4,%2 mov %1,etab_%3(%4) %endmacro ; Basic MOV and XOR Operations for last round %ifdef LAST_ROUND_TABLES %macro lr_xor 4 movzx %4,%2 xor %1,eltab_%3(%4) %endmacro %macro lr_mov 4 movzx %4,%2 mov %1,eltab_%3(%4) %endmacro %else %macro lr_xor 4 movzx %4,%2 movzx %4,etab_b(%4) %if %3 != 0 shl %4,8*%3 %endif xor %1,%4 %endmacro %macro lr_mov 4 movzx %4,%2 movzx %1,etab_b(%4) %if %3 != 0 shl %1,8*%3 %endif %endmacro %endif %macro enc_round 0 add ebp,16 save 0,ebp mov esi,[ebp+8] mov edi,[ebp+12] rnd_fun nr_xor, nr_mov mov eax,ebp mov ecx,esi mov edx,edi restore ebp,0 xor eax,[ebp] xor ebx,[ebp+4] %endmacro %macro enc_last_round 0 add ebp,16 save 0,ebp mov esi,[ebp+8] mov edi,[ebp+12] rnd_fun lr_xor, lr_mov mov eax,ebp restore ebp,0 xor eax,[ebp] xor ebx,[ebp+4] %endmacro section .text align=32 ; AES Encryption Subroutine do_name aes_encrypt sub esp,stk_spc mov [esp+16],ebp mov [esp+12],ebx mov [esp+ 8],esi mov [esp+ 4],edi mov esi,[esp+in_blk+stk_spc] ; input pointer mov eax,[esi ] mov ebx,[esi+ 4] mov ecx,[esi+ 8] mov edx,[esi+12] mov ebp,[esp+ctx+stk_spc] ; key pointer movzx edi,byte [ebp+4*KS_LENGTH] xor eax,[ebp ] xor ebx,[ebp+ 4] xor ecx,[ebp+ 8] xor edx,[ebp+12] ; determine the number of rounds cmp edi,10*16 je .3 cmp edi,12*16 je .2 cmp edi,14*16 je .1 mov eax,-1 jmp .5 .1: enc_round enc_round .2: enc_round enc_round .3: enc_round enc_round enc_round enc_round enc_round enc_round enc_round enc_round enc_round enc_last_round mov edx,[esp+out_blk+stk_spc] mov [edx],eax mov [edx+4],ebx mov [edx+8],esi mov [edx+12],edi xor eax,eax .5: mov ebp,[esp+16] mov ebx,[esp+12] mov esi,[esp+ 8] mov edi,[esp+ 4] add esp,stk_spc do_exit %endif %ifdef DECRYPTION extern t_in %define dtab_0(x) [t_in+4*x] %define dtab_1(x) [t_in+1024+4*x] %define dtab_2(x) [t_in+2048+4*x] %define dtab_3(x) [t_in+3072+4*x] %ifdef LAST_ROUND_TABLES extern t_il %define dltab_0(x) [t_il+4*x] %define dltab_1(x) [t_il+1024+4*x] %define dltab_2(x) [t_il+2048+4*x] %define dltab_3(x) [t_il+3072+4*x] %else extern _t_ibox %define dtab_x(x) byte [_t_ibox+x] %endif %macro irn_fun 2 rol eax,16 %1 esi, cl, 0, ebp %1 esi, bh, 1, ebp %1 esi, al, 2, ebp %1 edi, dl, 0, ebp %1 edi, ch, 1, ebp %1 edi, ah, 3, ebp %2 ebp, bl, 0, ebp shr eax,16 and ebx,0xffff0000 or ebx,eax shr ecx,16 %1 ebp, bh, 1, eax %1 ebp, ch, 3, eax %2 eax, cl, 2, ecx %1 eax, bl, 0, ecx %1 eax, dh, 1, ecx shr ebx,16 shr edx,16 %1 esi, dh, 3, ecx %1 ebp, dl, 2, ecx %1 eax, bh, 3, ecx %1 edi, bl, 2, ecx %endmacro ; Basic MOV and XOR Operations for normal rounds %macro ni_xor 4 movzx %4,%2 xor %1,dtab_%3(%4) %endmacro %macro ni_mov 4 movzx %4,%2 mov %1,dtab_%3(%4) %endmacro ; Basic MOV and XOR Operations for last round %ifdef LAST_ROUND_TABLES %macro li_xor 4 movzx %4,%2 xor %1,dltab_%3(%4) %endmacro %macro li_mov 4 movzx %4,%2 mov %1,dltab_%3(%4) %endmacro %else %macro li_xor 4 movzx %4,%2 movzx %4,dtab_x(%4) %if %3 != 0 shl %4,8*%3 %endif xor %1,%4 %endmacro %macro li_mov 4 movzx %4,%2 movzx %1,dtab_x(%4) %if %3 != 0 shl %1,8*%3 %endif %endmacro %endif %macro dec_round 0 %ifdef AES_REV_DKS add ebp,16 %else sub ebp,16 %endif save 0,ebp mov esi,[ebp+8] mov edi,[ebp+12] irn_fun ni_xor, ni_mov mov ebx,ebp mov ecx,esi mov edx,edi restore ebp,0 xor eax,[ebp] xor ebx,[ebp+4] %endmacro %macro dec_last_round 0 %ifdef AES_REV_DKS add ebp,16 %else sub ebp,16 %endif save 0,ebp mov esi,[ebp+8] mov edi,[ebp+12] irn_fun li_xor, li_mov mov ebx,ebp restore ebp,0 xor eax,[ebp] xor ebx,[ebp+4] %endmacro section .text ; AES Decryption Subroutine do_name aes_decrypt sub esp,stk_spc mov [esp+16],ebp mov [esp+12],ebx mov [esp+ 8],esi mov [esp+ 4],edi ; input four columns and xor in first round key mov esi,[esp+in_blk+stk_spc] ; input pointer mov eax,[esi ] mov ebx,[esi+ 4] mov ecx,[esi+ 8] mov edx,[esi+12] lea esi,[esi+16] mov ebp,[esp+ctx+stk_spc] ; key pointer movzx edi,byte[ebp+4*KS_LENGTH] %ifndef AES_REV_DKS ; if decryption key schedule is not reversed lea ebp,[ebp+edi] ; we have to access it from the top down %endif xor eax,[ebp ] ; key schedule xor ebx,[ebp+ 4] xor ecx,[ebp+ 8] xor edx,[ebp+12] ; determine the number of rounds cmp edi,10*16 je .3 cmp edi,12*16 je .2 cmp edi,14*16 je .1 mov eax,-1 jmp .5 .1: dec_round dec_round .2: dec_round dec_round .3: dec_round dec_round dec_round dec_round dec_round dec_round dec_round dec_round dec_round dec_last_round ; move final values to the output array. mov ebp,[esp+out_blk+stk_spc] mov [ebp],eax mov [ebp+4],ebx mov [ebp+8],esi mov [ebp+12],edi xor eax,eax .5: mov ebp,[esp+16] mov ebx,[esp+12] mov esi,[esp+ 8] mov edi,[esp+ 4] add esp,stk_spc do_exit %endif %ifidn __OUTPUT_FORMAT__,elf section .note.GNU-stack noalloc noexec nowrite progbits %endif %ifidn __OUTPUT_FORMAT__,elf32 section .note.GNU-stack noalloc noexec nowrite progbits %endif %ifidn __OUTPUT_FORMAT__,elf64 section .note.GNU-stack noalloc noexec nowrite progbits %endif