From c8c8cc517dae089c1241890133837339a716f225 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 10 Dec 2014 19:24:39 +0100 Subject: [PATCH] Linux/MacOSX: Implement generating more than one keyfile, specifying the size of the generated keyfiles and letting VeraCrypt choose random size values. --- src/Core/RandomNumberGenerator.cpp | 60 +- src/Core/RandomNumberGenerator.h | 6 +- src/Main/Forms/Forms.cpp | 47 ++ src/Main/Forms/Forms.h | 10 + src/Main/Forms/KeyfileGeneratorDialog.cpp | 107 ++- src/Main/Forms/KeyfileGeneratorDialog.h | 1 + src/Main/Forms/TrueCrypt.fbp | 795 +++++++++++++++++++++- src/Main/SystemPrecompiled.h | 1 + 8 files changed, 991 insertions(+), 36 deletions(-) diff --git a/src/Core/RandomNumberGenerator.cpp b/src/Core/RandomNumberGenerator.cpp index ab3aad6b..ae0f8248 100644 --- a/src/Core/RandomNumberGenerator.cpp +++ b/src/Core/RandomNumberGenerator.cpp @@ -65,45 +65,63 @@ namespace VeraCrypt } } - void RandomNumberGenerator::GetData (const BufferPtr &buffer, bool fast) + void RandomNumberGenerator::GetData (const BufferPtr &buffer, bool fast, bool allowAnyLength) { if (!Running) throw NotInitialized (SRC_POS); - if (buffer.Size() > PoolSize) + if (!allowAnyLength && (buffer.Size() > PoolSize)) throw ParameterIncorrect (SRC_POS); ScopeLock lock (AccessMutex); + size_t bufferLen = buffer.Size(), loopLen; + byte* pbBuffer = buffer.Get(); // Poll system for data AddSystemDataToPool (fast); HashMixPool(); - // Transfer bytes from pool to output buffer - for (size_t i = 0; i < buffer.Size(); ++i) + while (bufferLen > 0) { - buffer[i] += Pool[ReadOffset++]; + if (bufferLen > PoolSize) + { + loopLen = PoolSize; + bufferLen -= PoolSize; + } + else + { + loopLen = bufferLen; + bufferLen = 0; + } - if (ReadOffset >= PoolSize) - ReadOffset = 0; - } + // Transfer bytes from pool to output buffer + for (size_t i = 0; i < loopLen; ++i) + { + pbBuffer[i] += Pool[ReadOffset++]; - // Invert and mix the pool - for (size_t i = 0; i < Pool.Size(); ++i) - { - Pool[i] = ~Pool[i]; - } + if (ReadOffset >= PoolSize) + ReadOffset = 0; + } - AddSystemDataToPool (true); - HashMixPool(); + // Invert and mix the pool + for (size_t i = 0; i < Pool.Size(); ++i) + { + Pool[i] = ~Pool[i]; + } - // XOR the current pool content into the output buffer to prevent pool state leaks - for (size_t i = 0; i < buffer.Size(); ++i) - { - buffer[i] ^= Pool[ReadOffset++]; + AddSystemDataToPool (true); + HashMixPool(); - if (ReadOffset >= PoolSize) - ReadOffset = 0; + // XOR the current pool content into the output buffer to prevent pool state leaks + for (size_t i = 0; i < loopLen; ++i) + { + pbBuffer[i] ^= Pool[ReadOffset++]; + + if (ReadOffset >= PoolSize) + ReadOffset = 0; + } + + pbBuffer += loopLen; } } diff --git a/src/Core/RandomNumberGenerator.h b/src/Core/RandomNumberGenerator.h index 2c7587c9..2f61cd9a 100644 --- a/src/Core/RandomNumberGenerator.h +++ b/src/Core/RandomNumberGenerator.h @@ -19,8 +19,8 @@ namespace VeraCrypt { public: static void AddToPool (const ConstBufferPtr &buffer); - static void GetData (const BufferPtr &buffer) { GetData (buffer, false); } - static void GetDataFast (const BufferPtr &buffer) { GetData (buffer, true); } + static void GetData (const BufferPtr &buffer, bool allowAnyLength = false) { GetData (buffer, false, allowAnyLength); } + static void GetDataFast (const BufferPtr &buffer, bool allowAnyLength = false) { GetData (buffer, true, allowAnyLength); } static shared_ptr GetHash (); static bool IsEnrichedByUser () { return EnrichedByUser; } static bool IsRunning () { return Running; } @@ -34,7 +34,7 @@ namespace VeraCrypt protected: static void AddSystemDataToPool (bool fast); - static void GetData (const BufferPtr &buffer, bool fast); + static void GetData (const BufferPtr &buffer, bool fast, bool allowAnyLength); static void HashMixPool (); static void Test (); RandomNumberGenerator (); diff --git a/src/Main/Forms/Forms.cpp b/src/Main/Forms/Forms.cpp index 17333a79..013ad40c 100644 --- a/src/Main/Forms/Forms.cpp +++ b/src/Main/Forms/Forms.cpp @@ -1370,6 +1370,51 @@ KeyfileGeneratorDialogBase::KeyfileGeneratorDialogBase( wxWindow* parent, wxWind bSizer144->Add( sbSizer43, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + wxBoxSizer* bSizer162; + bSizer162 = new wxBoxSizer( wxVERTICAL ); + + wxFlexGridSizer* fgSizer8; + fgSizer8 = new wxFlexGridSizer( 3, 3, 0, 0 ); + fgSizer8->AddGrowableCol( 2 ); + fgSizer8->SetFlexibleDirection( wxBOTH ); + fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText60 = new wxStaticText( this, wxID_ANY, _("Number of keyfiles:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText60->Wrap( -1 ); + fgSizer8->Add( m_staticText60, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + NumberOfKeyfiles = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 9999999, 1 ); + fgSizer8->Add( NumberOfKeyfiles, 0, wxALL, 5 ); + + m_panel18 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + fgSizer8->Add( m_panel18, 1, wxEXPAND | wxALL, 5 ); + + m_staticText63 = new wxStaticText( this, wxID_ANY, _("Keyfiles size (in Bytes):"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText63->Wrap( -1 ); + fgSizer8->Add( m_staticText63, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + KeyfilesSize = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 64, 1048576, 64 ); + fgSizer8->Add( KeyfilesSize, 0, wxALL, 5 ); + + RandomSizeCheckBox = new wxCheckBox( this, wxID_ANY, _("Random size (64 <-> 1048576)"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer8->Add( RandomSizeCheckBox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_staticText65 = new wxStaticText( this, wxID_ANY, _("Keyfiles base name:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText65->Wrap( -1 ); + fgSizer8->Add( m_staticText65, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + KeyfilesBaseName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer8->Add( KeyfilesBaseName, 0, wxALL, 5 ); + + m_panel19 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + fgSizer8->Add( m_panel19, 1, wxEXPAND | wxALL, 5 ); + + + bSizer162->Add( fgSizer8, 1, wxEXPAND, 5 ); + + + bSizer144->Add( bSizer162, 1, wxALL|wxEXPAND, 5 ); + wxBoxSizer* bSizer146; bSizer146 = new wxBoxSizer( wxHORIZONTAL ); @@ -1398,6 +1443,7 @@ KeyfileGeneratorDialogBase::KeyfileGeneratorDialogBase( wxWindow* parent, wxWind this->Connect( wxEVT_MOTION, wxMouseEventHandler( KeyfileGeneratorDialogBase::OnMouseMotion ) ); HashChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnHashSelected ), NULL, this ); ShowRandomPoolCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnShowRandomPoolCheckBoxClicked ), NULL, this ); + RandomSizeCheckBox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnRandomSizeCheckBoxClicked ), NULL, this ); GenerateButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnGenerateButtonClick ), NULL, this ); } @@ -1407,6 +1453,7 @@ KeyfileGeneratorDialogBase::~KeyfileGeneratorDialogBase() this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( KeyfileGeneratorDialogBase::OnMouseMotion ) ); HashChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnHashSelected ), NULL, this ); ShowRandomPoolCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnShowRandomPoolCheckBoxClicked ), NULL, this ); + RandomSizeCheckBox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnRandomSizeCheckBoxClicked ), NULL, this ); GenerateButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KeyfileGeneratorDialogBase::OnGenerateButtonClick ), NULL, this ); } diff --git a/src/Main/Forms/Forms.h b/src/Main/Forms/Forms.h index 60d61b0a..e56f9919 100644 --- a/src/Main/Forms/Forms.h +++ b/src/Main/Forms/Forms.h @@ -410,12 +410,22 @@ namespace VeraCrypt wxStaticText* RandomPoolStaticText; wxCheckBox* ShowRandomPoolCheckBox; wxStaticText* MouseStaticText; + wxStaticText* m_staticText60; + wxSpinCtrl* NumberOfKeyfiles; + wxPanel* m_panel18; + wxStaticText* m_staticText63; + wxSpinCtrl* KeyfilesSize; + wxCheckBox* RandomSizeCheckBox; + wxStaticText* m_staticText65; + wxTextCtrl* KeyfilesBaseName; + wxPanel* m_panel19; wxButton* GenerateButton; // Virtual event handlers, overide them in your derived class virtual void OnMouseMotion( wxMouseEvent& event ) { event.Skip(); } virtual void OnHashSelected( wxCommandEvent& event ) { event.Skip(); } virtual void OnShowRandomPoolCheckBoxClicked( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRandomSizeCheckBoxClicked( wxCommandEvent& event ) { event.Skip(); } virtual void OnGenerateButtonClick( wxCommandEvent& event ) { event.Skip(); } diff --git a/src/Main/Forms/KeyfileGeneratorDialog.cpp b/src/Main/Forms/KeyfileGeneratorDialog.cpp index ce88ab09..5a24a255 100644 --- a/src/Main/Forms/KeyfileGeneratorDialog.cpp +++ b/src/Main/Forms/KeyfileGeneratorDialog.cpp @@ -48,20 +48,97 @@ namespace VeraCrypt { try { - FilePathList files = Gui->SelectFiles (Gui->GetActiveWindow(), wxEmptyString, true); - - if (files.empty()) - return; - - SecureBuffer keyfileBuffer (VolumePassword::MaxSize); - RandomNumberGenerator::GetData (keyfileBuffer); - + int keyfilesCount = NumberOfKeyfiles->GetValue(); + int keyfilesSize = KeyfilesSize->GetValue(); + bool useRandomSize = RandomSizeCheckBox->IsChecked(); + wxString keyfileBaseName = KeyfilesBaseName->GetValue(); + keyfileBaseName.Trim(true); + keyfileBaseName.Trim(false); + + if (keyfileBaseName.IsEmpty()) { - File keyfile; - keyfile.Open (*files.front(), File::CreateWrite); - keyfile.Write (keyfileBuffer); + Gui->ShowWarning("KEYFILE_EMPTY_BASE_NAME"); + return; } + + wxFileName baseFileName = wxFileName::FileName (keyfileBaseName); + if (!baseFileName.IsOk()) + { + Gui->ShowWarning("KEYFILE_INVALID_BASE_NAME"); + return; + } + + DirectoryPath keyfilesDir = Gui->SelectDirectory (Gui->GetActiveWindow(), LangString["SELECT_KEYFILE_GENERATION_DIRECTORY"], false); + if (keyfilesDir.IsEmpty()) + return; + + wxFileName dirFileName = wxFileName::DirName( wstring(keyfilesDir).c_str() ); + if (!dirFileName.IsDirWritable ()) + { + Gui->ShowWarning(L"You don't have write permission on the selected directory"); + return; + } + + wxBusyCursor busy; + for (int i = 0; i < keyfilesCount; i++) + { + int bufferLen; + if (useRandomSize) + { + SecureBuffer sizeBuffer (sizeof(int)); + RandomNumberGenerator::GetData (sizeBuffer, true); + + memcpy(&bufferLen, sizeBuffer.Ptr(), sizeof(int)); + /* since keyfilesSize < 1024 * 1024, we mask with 0x000FFFFF */ + bufferLen = (long) (((unsigned long) bufferLen) & 0x000FFFFF); + + bufferLen %= ((1024*1024 - 64) + 1); + bufferLen += 64; + } + else + bufferLen = keyfilesSize; + + SecureBuffer keyfileBuffer (bufferLen); + RandomNumberGenerator::GetData (keyfileBuffer, true); + + wstringstream convertStream; + convertStream << i; + wxString suffix = L"_"; + suffix += convertStream.str().c_str(); + + wxFileName keyfileName; + if (i == 0) + { + keyfileName.Assign(dirFileName.GetPath(), keyfileBaseName); + } + else + { + if (baseFileName.HasExt()) + { + keyfileName.Assign(dirFileName.GetPath(), baseFileName.GetName() + suffix + L"." + baseFileName.GetExt()); + } + else + { + keyfileName.Assign(dirFileName.GetPath(), keyfileBaseName + suffix); + } + } + + if (keyfileName.Exists()) + { + wxString msg = wxString::Format(LangString["KEYFILE_ALREADY_EXISTS"], keyfileName.GetFullPath()); + if (!Gui->AskYesNo (msg, false, true)) + return; + } + + { + FilePath keyfilePath((const wchar_t*) keyfileName.GetFullPath()); + File keyfile; + keyfile.Open (keyfilePath, File::CreateWrite); + keyfile.Write (keyfileBuffer); + } + + } Gui->ShowInfo ("KEYFILE_CREATED"); } catch (exception &e) @@ -96,6 +173,14 @@ namespace VeraCrypt RandomPoolStaticText->SetLabel (L""); } + void KeyfileGeneratorDialog::OnRandomSizeCheckBoxClicked (wxCommandEvent& event) + { + if (!event.IsChecked()) + KeyfilesSize->Enable(); + else + KeyfilesSize->Disable(); + } + void KeyfileGeneratorDialog::ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer, bool appendDots) { wxString str; diff --git a/src/Main/Forms/KeyfileGeneratorDialog.h b/src/Main/Forms/KeyfileGeneratorDialog.h index 4f184909..1d73a687 100644 --- a/src/Main/Forms/KeyfileGeneratorDialog.h +++ b/src/Main/Forms/KeyfileGeneratorDialog.h @@ -25,6 +25,7 @@ namespace VeraCrypt void OnHashSelected (wxCommandEvent& event); void OnMouseMotion (wxMouseEvent& event); void OnShowRandomPoolCheckBoxClicked (wxCommandEvent& event); + void OnRandomSizeCheckBoxClicked( wxCommandEvent& event ); void ShowBytes (wxStaticText *textCtrl, const ConstBufferPtr &buffer, bool appendDots = true); HashList Hashes; diff --git a/src/Main/Forms/TrueCrypt.fbp b/src/Main/Forms/TrueCrypt.fbp index 1a173020..82c1fba6 100644 --- a/src/Main/Forms/TrueCrypt.fbp +++ b/src/Main/Forms/TrueCrypt.fbp @@ -9561,10 +9561,803 @@ + 5 + wxALL|wxEXPAND + 1 + + + bSizer162 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 3 + wxBOTH + 2 + + 0 + + fgSizer8 + wxFLEX_GROWMODE_SPECIFIED + none + 3 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Number of keyfiles: + + 0 + + + 0 + + 1 + m_staticText60 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 1 + 9999999 + + 0 + + 1 + + 0 + + 1 + NumberOfKeyfiles + 1 + + + protected + 1 + + Resizable + 1 + + wxSP_ARROW_KEYS + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panel18 + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Keyfiles size (in Bytes): + + 0 + + + 0 + + 1 + m_staticText63 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 64 + 1048576 + + 0 + + 64 + + 0 + + 1 + KeyfilesSize + 1 + + + protected + 1 + + Resizable + 1 + + wxSP_ARROW_KEYS + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Random size (64 <-> 1048576) + + 0 + + + 0 + + 1 + RandomSizeCheckBox + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + OnRandomSizeCheckBoxClicked + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Keyfiles base name: + + 0 + + + 0 + + 1 + m_staticText65 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + KeyfilesBaseName + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panel19 + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 wxEXPAND 0 - + bSizer146 wxHORIZONTAL diff --git a/src/Main/SystemPrecompiled.h b/src/Main/SystemPrecompiled.h index 956760ff..e4b9223c 100644 --- a/src/Main/SystemPrecompiled.h +++ b/src/Main/SystemPrecompiled.h @@ -24,6 +24,7 @@ #endif #include +#include #include #include #include