From c84bcd4b474b994cd7aec29ee3a8412d564ce4b2 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 9 Aug 2018 19:18:18 +0200 Subject: Linux/MacOSX/FreeBSD: Implement benchmarking for Hash and PKCS-5 PRF algorithms. --- src/Main/Forms/BenchmarkDialog.cpp | 345 +++++++++++++++++++++++++++++-------- 1 file changed, 275 insertions(+), 70 deletions(-) (limited to 'src/Main/Forms/BenchmarkDialog.cpp') diff --git a/src/Main/Forms/BenchmarkDialog.cpp b/src/Main/Forms/BenchmarkDialog.cpp index 440bc1d9..18712274 100644 --- a/src/Main/Forms/BenchmarkDialog.cpp +++ b/src/Main/Forms/BenchmarkDialog.cpp @@ -38,38 +38,125 @@ namespace VeraCrypt BufferSizeChoice->Append (Gui->SizeToString (size), (void *) size); } + BenchmarkChoice->Select (0); BufferSizeChoice->Select (1); - - list colPermilles; - BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1); - colPermilles.push_back (322); - - BenchmarkListCtrl->InsertColumn (ColumnEncryption, LangString["ENCRYPTION"], wxLIST_FORMAT_RIGHT, 1); - colPermilles.push_back (226); - - BenchmarkListCtrl->InsertColumn (ColumnDecryption, LangString["DECRYPTION"], wxLIST_FORMAT_RIGHT, 1); - colPermilles.push_back (226); - - BenchmarkListCtrl->InsertColumn (ColumnMean, LangString["MEAN"], wxLIST_FORMAT_RIGHT, 1); - colPermilles.push_back (226); - - Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false); - Gui->SetListCtrlHeight (BenchmarkListCtrl, 14); - Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles); + + UpdateBenchmarkList (); + + wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST); // wxFILTER_NUMERIC does not exclude - . , etc. + const wxChar *valArr[] = { L"0", L"1", L"2", L"3", L"4", L"5", L"6", L"7", L"8", L"9" }; + validator.SetIncludes (wxArrayString (array_capacity (valArr), (const wxChar **) &valArr)); + VolumePimText->SetValidator (validator); Layout(); Fit(); Center(); } + + void BenchmarkDialog::UpdateBenchmarkList () + { + int index = BenchmarkChoice->GetSelection (); + if (index == 1) + { + // PRF case + m_volumePimLabel->Show (); + VolumePimText->Show (); + + BufferSizeChoice->Hide (); + m_bufferSizeLabel->Hide (); + } + else + { + m_volumePimLabel->Hide (); + VolumePimText->Hide (); + + BufferSizeChoice->Show (); + m_bufferSizeLabel->Show (); + } + + BenchmarkListCtrl->DeleteAllItems(); + BenchmarkListCtrl->DeleteAllColumns(); + + if (index == 0) + { + // encryption case + list colPermilles; + BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (322); + + BenchmarkListCtrl->InsertColumn (ColumnEncryption, LangString["ENCRYPTION"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + BenchmarkListCtrl->InsertColumn (ColumnDecryption, LangString["DECRYPTION"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + BenchmarkListCtrl->InsertColumn (ColumnMean, LangString["MEAN"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false); + Gui->SetListCtrlHeight (BenchmarkListCtrl, 14); + Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles); + } + else if (index == 1) + { + // PRF case + list colPermilles; + BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (322); + + BenchmarkListCtrl->InsertColumn (ColumnTime, LangString["TIME"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + BenchmarkListCtrl->InsertColumn (ColumnIterations, LangString["ITERATIONS"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false); + Gui->SetListCtrlHeight (BenchmarkListCtrl, 14); + Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles); + } + else + { + // Hash case + list colPermilles; + BenchmarkListCtrl->InsertColumn (ColumnAlgorithm, LangString["ALGORITHM"], wxLIST_FORMAT_LEFT, 1); + colPermilles.push_back (322); + + BenchmarkListCtrl->InsertColumn (ColumnEncryption, LangString["MEAN"], wxLIST_FORMAT_RIGHT, 1); + colPermilles.push_back (226); + + Gui->SetListCtrlWidth (BenchmarkListCtrl, 62, false); + Gui->SetListCtrlHeight (BenchmarkListCtrl, 14); + Gui->SetListCtrlColumnWidths (BenchmarkListCtrl, colPermilles); + } + } + + void BenchmarkDialog::OnBenchmarkChoiceSelected (wxCommandEvent& event) + { + UpdateBenchmarkList (); + + Layout(); + Fit(); + } void BenchmarkDialog::OnBenchmarkButtonClick (wxCommandEvent& event) { list results; wxBusyCursor busy; - Buffer buffer ((size_t) Gui->GetSelectedData (BufferSizeChoice)); + int opIndex = BenchmarkChoice->GetSelection (); + Buffer buffer ((opIndex == 1)? sizeof (unsigned long) : (size_t) Gui->GetSelectedData (BufferSizeChoice)); + + if (opIndex == 1) + { + unsigned long pim = 0; + if (!VolumePimText->GetValue().ToULong (&pim)) + pim = 0; + + memcpy (buffer.Ptr (), &pim, sizeof (unsigned long)); + } + - BenchmarkThreadRoutine routine(this, results, buffer); + BenchmarkThreadRoutine routine(this, results, buffer, opIndex); Gui->ExecuteWaitThreadRoutine (this, &routine); BenchmarkListCtrl->DeleteAllItems(); @@ -79,9 +166,21 @@ namespace VeraCrypt vector fields (BenchmarkListCtrl->GetColumnCount()); fields[ColumnAlgorithm] = result.AlgorithmName; - fields[ColumnEncryption] = Gui->SpeedToString (result.EncryptionSpeed); - fields[ColumnDecryption] = Gui->SpeedToString (result.DecryptionSpeed); - fields[ColumnMean] = Gui->SpeedToString (result.MeanSpeed); + if (opIndex == 0) + { + fields[ColumnEncryption] = Gui->SpeedToString (result.EncryptionSpeed); + fields[ColumnDecryption] = Gui->SpeedToString (result.DecryptionSpeed); + fields[ColumnMean] = Gui->SpeedToString (result.MeanSpeed); + } + else if (opIndex == 1) + { + fields[ColumnTime] = wxString::Format (wxT("%llu ms"), (unsigned long long) result.Time); + fields[ColumnIterations] = wxString::Format (wxT("%llu"), (unsigned long long) result.Iterations); + } + else + { + fields[ColumnHashMean] = Gui->SpeedToString (result.MeanSpeed); + } Gui->AppendToListCtrl (BenchmarkListCtrl, fields); } @@ -94,78 +193,184 @@ namespace VeraCrypt Fit(); } - void BenchmarkDialog::DoBenchmark (list& results, Buffer& buffer) + void BenchmarkDialog::DoBenchmark (list& results, Buffer& buffer, int opIndex) { try { - EncryptionAlgorithmList encryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms(); - foreach (shared_ptr ea, encryptionAlgorithms) + if (opIndex == 0) { - if (!ea->IsDeprecated()) + EncryptionAlgorithmList encryptionAlgorithms = EncryptionAlgorithm::GetAvailableAlgorithms(); + foreach (shared_ptr ea, encryptionAlgorithms) { - BenchmarkResult result; - result.AlgorithmName = ea->GetName(true); + if (!ea->IsDeprecated()) + { + BenchmarkResult result; + result.AlgorithmName = ea->GetName(true); - Buffer key (ea->GetKeySize()); - ea->SetKey (key); + Buffer key (ea->GetKeySize()); + ea->SetKey (key); - shared_ptr xts (new EncryptionModeXTS); - xts->SetKey (key); - ea->SetMode (xts); + shared_ptr xts (new EncryptionModeXTS); + xts->SetKey (key); + ea->SetMode (xts); - wxLongLong startTime = wxGetLocalTimeMillis(); + wxLongLong startTime = wxGetLocalTimeMillis(); - // CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency gradually changes depending on CPU load). - do - { - ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); - } - while (wxGetLocalTimeMillis().GetValue() - startTime.GetValue() < 20); + // CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency gradually changes depending on CPU load). + do + { + ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + } + while (wxGetLocalTimeMillis().GetValue() - startTime.GetValue() < 20); - uint64 size = 0; - uint64 time; - startTime = wxGetLocalTimeMillis(); + uint64 size = 0; + uint64 time; + startTime = wxGetLocalTimeMillis(); - do - { - ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); - size += buffer.Size(); - time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue()); - } - while (time < 100); + do + { + ea->EncryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + size += buffer.Size(); + time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue()); + } + while (time < 100); - result.EncryptionSpeed = size * 1000 / time; + result.EncryptionSpeed = size * 1000 / time; - startTime = wxGetLocalTimeMillis(); - size = 0; + startTime = wxGetLocalTimeMillis(); + size = 0; + + do + { + ea->DecryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); + size += buffer.Size(); + time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue()); + } + while (time < 100); + + result.DecryptionSpeed = size * 1000 / time; + result.MeanSpeed = (result.EncryptionSpeed + result.DecryptionSpeed) / 2; + + bool inserted = false; + for (list ::iterator i = results.begin(); i != results.end(); ++i) + { + if (i->MeanSpeed < result.MeanSpeed) + { + results.insert (i, result); + inserted = true; + break; + } + } - do + if (!inserted) + results.push_back (result); + } + } + } + else if (opIndex == 1) + { + Buffer dk(MASTER_KEYDATA_SIZE); + Buffer salt(64); + const char *tmp_salt = {"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"}; + unsigned long pim; + Pkcs5KdfList prfList = Pkcs5Kdf::GetAvailableAlgorithms (false); + VolumePassword password ((const byte*) "passphrase-1234567890", 21); + + memcpy (&pim, buffer.Ptr (), sizeof (unsigned long)); + memcpy (salt.Ptr(), tmp_salt, 64); + + foreach (shared_ptr prf, prfList) + { + if (!prf->IsDeprecated()) { - ea->DecryptSectors (buffer, 0, buffer.Size() / ENCRYPTION_DATA_UNIT_SIZE, ENCRYPTION_DATA_UNIT_SIZE); - size += buffer.Size(); + BenchmarkResult result; + result.AlgorithmName = prf->GetName (); + result.Iterations = (uint64) prf->GetIterationCount (pim); + + uint64 time; + wxLongLong startTime = wxGetLocalTimeMillis(); + + for (int i = 1; i <= 2; i++) + { + prf->DeriveKey (dk, password, pim, salt); + } + time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue()); - } - while (time < 100); - result.DecryptionSpeed = size * 1000 / time; - result.MeanSpeed = (result.EncryptionSpeed + result.DecryptionSpeed) / 2; + result.Time = time / 2; + + bool inserted = false; + for (list ::iterator i = results.begin(); i != results.end(); ++i) + { + if (i->Time > result.Time) + { + results.insert (i, result); + inserted = true; + break; + } + } - bool inserted = false; - for (list ::iterator i = results.begin(); i != results.end(); ++i) + if (!inserted) + results.push_back (result); + } + } + + } + else + { + Buffer digest (1024); + HashList hashAlgorithms = Hash::GetAvailableAlgorithms (); + foreach (shared_ptr hash, hashAlgorithms) + { + if (!hash->IsDeprecated()) { - if (i->MeanSpeed < result.MeanSpeed) + BenchmarkResult result; + result.AlgorithmName = hash->GetName (); + + uint64 size = 0; + uint64 time; + wxLongLong startTime = wxGetLocalTimeMillis(); + + // CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency gradually changes depending on CPU load). + do { - results.insert (i, result); - inserted = true; - break; + hash->Init (); + hash->ProcessData (digest); + hash->GetDigest (digest); } - } + while (wxGetLocalTimeMillis().GetValue() - startTime.GetValue() < 100); + - if (!inserted) - results.push_back (result); + startTime = wxGetLocalTimeMillis(); + do + { + hash->Init (); + hash->ProcessData (buffer); + hash->GetDigest (digest); + time = (uint64) (wxGetLocalTimeMillis().GetValue() - startTime.GetValue()); + size += buffer.Size (); + } + while (time < 2000); + + result.MeanSpeed = size * 1000 / time; + + bool inserted = false; + for (list ::iterator i = results.begin(); i != results.end(); ++i) + { + if (i->MeanSpeed < result.MeanSpeed) + { + results.insert (i, result); + inserted = true; + break; + } + } + + if (!inserted) + results.push_back (result); + + } } } - } catch (exception &e) { -- cgit v1.2.3