mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-10-21 22:02:37 +00:00
Wipe token keyfile buffers on failure and release
Use a size_t counter in burn so large erasures retain their full length. Install cleanup guards before token verification and keyfile application, including the Windows token export path. Reserve the complete EMV keyfile output before copying its components, and wipe temporary components on every exit. Erase cached card data before clearing or replacing it, including when copying a card fails. Validation: Linux console and GUI builds with algorithm tests; cleanup checks with GCC and Clang UBSan. PR 1816 still applies cleanly.
This commit is contained in:
@@ -13001,6 +13001,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
|
||||
finally_do ({ NormalCursor(); });
|
||||
|
||||
vector <uint8> keyfileData;
|
||||
finally_do_arg (vector <uint8> *, &keyfileData, { if (!finally_arg->empty()) burn (&finally_arg->front(), finally_arg->size()); });
|
||||
|
||||
keyfile->GetKeyfileData (keyfileData);
|
||||
|
||||
@@ -13011,8 +13012,6 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
|
||||
return 1;
|
||||
}
|
||||
|
||||
finally_do_arg (vector <uint8> *, &keyfileData, { burn (&finally_arg->front(), finally_arg->size()); });
|
||||
|
||||
if (!SaveBufferToFile ((char *) &keyfileData.front(), keyfilePath, (DWORD) keyfileData.size(), FALSE, FALSE))
|
||||
throw SystemException (SRC_POS);
|
||||
}
|
||||
|
||||
+27
-8
@@ -67,15 +67,18 @@ namespace VeraCrypt
|
||||
Clear();
|
||||
}
|
||||
|
||||
EMVCard::EMVCard(const EMVCard& other) :
|
||||
SCard(other),
|
||||
m_aid(other.m_aid),
|
||||
m_supportedAids(other.m_supportedAids),
|
||||
m_iccCert(other.m_iccCert),
|
||||
m_issuerCert(other.m_issuerCert),
|
||||
m_cplcData(other.m_cplcData),
|
||||
m_lastPANDigits(other.m_lastPANDigits)
|
||||
EMVCard::EMVCard(const EMVCard& other) : SCard()
|
||||
{
|
||||
try
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// The destructor won't run if copying a later field fails.
|
||||
Clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
EMVCard::EMVCard(EMVCard&& other) :
|
||||
@@ -93,6 +96,7 @@ namespace VeraCrypt
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
Clear();
|
||||
SCard::operator=(other);
|
||||
m_aid = other.m_aid;
|
||||
m_supportedAids = other.m_supportedAids;
|
||||
@@ -108,6 +112,7 @@ namespace VeraCrypt
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
Clear();
|
||||
SCard::operator=(other);
|
||||
m_reader = std::move(other.m_reader);
|
||||
m_aid = std::move(other.m_aid);
|
||||
@@ -124,9 +129,17 @@ namespace VeraCrypt
|
||||
{
|
||||
m_aid.clear();
|
||||
m_supportedAids.clear();
|
||||
if (!m_iccCert.empty())
|
||||
burn(m_iccCert.data(), m_iccCert.size());
|
||||
m_iccCert.clear();
|
||||
if (!m_issuerCert.empty())
|
||||
burn(m_issuerCert.data(), m_issuerCert.size());
|
||||
m_issuerCert.clear();
|
||||
if (!m_cplcData.empty())
|
||||
burn(m_cplcData.data(), m_cplcData.size());
|
||||
m_cplcData.clear();
|
||||
if (!m_lastPANDigits.empty())
|
||||
burn(&m_lastPANDigits[0], m_lastPANDigits.size() * sizeof(wchar_t));
|
||||
m_lastPANDigits.clear();
|
||||
}
|
||||
|
||||
@@ -426,8 +439,14 @@ namespace VeraCrypt
|
||||
if (!issuerFound)
|
||||
throw EMVIssuerCertNotFound();
|
||||
|
||||
if (!m_iccCert.empty())
|
||||
burn(m_iccCert.data(), m_iccCert.size());
|
||||
m_iccCert = iccCert;
|
||||
if (!m_issuerCert.empty())
|
||||
burn(m_issuerCert.data(), m_issuerCert.size());
|
||||
m_issuerCert = issuerCert;
|
||||
if (!m_cplcData.empty())
|
||||
burn(m_cplcData.data(), m_cplcData.size());
|
||||
m_cplcData = cplcData;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,10 +79,15 @@ namespace VeraCrypt
|
||||
map <unsigned long int, shared_ptr<EMVCard>>::iterator emvCardsIt;
|
||||
shared_ptr<EMVCard> card;
|
||||
vector<uint8> iccCert;
|
||||
finally_do_arg (vector<uint8> *, &iccCert, { if (!finally_arg->empty()) burn (finally_arg->data(), finally_arg->size()); });
|
||||
vector<uint8> issuerCert;
|
||||
finally_do_arg (vector<uint8> *, &issuerCert, { if (!finally_arg->empty()) burn (finally_arg->data(), finally_arg->size()); });
|
||||
vector<uint8> cplcData;
|
||||
finally_do_arg (vector<uint8> *, &cplcData, { if (!finally_arg->empty()) burn (finally_arg->data(), finally_arg->size()); });
|
||||
bool addNewCard = true;
|
||||
|
||||
if (!keyfileData.empty())
|
||||
burn (keyfileData.data(), keyfileData.size());
|
||||
keyfileData.clear();
|
||||
|
||||
emvCardsIt = EMVToken::EMVCards.find(Token->SlotId);
|
||||
@@ -113,6 +118,16 @@ namespace VeraCrypt
|
||||
EMVToken::EMVCards.insert(make_pair(Token->SlotId, card));
|
||||
}
|
||||
|
||||
// Allocate before copying so vector growth cannot release keyfile material.
|
||||
size_t totalSize = iccCert.size();
|
||||
if (issuerCert.size() > keyfileData.max_size() - totalSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
totalSize += issuerCert.size();
|
||||
if (cplcData.size() > keyfileData.max_size() - totalSize)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
totalSize += cplcData.size();
|
||||
keyfileData.reserve(totalSize);
|
||||
|
||||
AppendData(keyfileData, iccCert.data(), iccCert.size(), 0, iccCert.size());
|
||||
AppendData(keyfileData, issuerCert.data(), issuerCert.size(), 0, issuerCert.size());
|
||||
AppendData(keyfileData, cplcData.data(), cplcData.size(), 0, cplcData.size());
|
||||
|
||||
@@ -254,6 +254,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
|
||||
{
|
||||
// Apply security token keyfile
|
||||
vector <uint8> keyfileData;
|
||||
finally_do_arg (vector <uint8> *, &keyfileData, { if (!finally_arg->empty()) burn (&finally_arg->front(), finally_arg->size()); });
|
||||
TokenKeyfilePath secPath (kf->FileName);
|
||||
Token::getTokenKeyfile (secPath)->GetKeyfileData (keyfileData);
|
||||
|
||||
@@ -286,7 +287,6 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con
|
||||
break;
|
||||
}
|
||||
|
||||
burn (&keyfileData.front(), keyfileData.size());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,9 +168,9 @@ namespace VeraCrypt
|
||||
|
||||
// Some tokens report success even if the new object was truncated to fit in the available memory
|
||||
vector <uint8> objectData;
|
||||
finally_do_arg(vector <uint8> *, &objectData, { if (!finally_arg->empty()) burn(&finally_arg->front(), finally_arg->size()); });
|
||||
|
||||
GetObjectAttribute(slotId, keyfileHandle, CKA_VALUE, objectData);
|
||||
finally_do_arg(vector <uint8> *, &objectData, { if (!finally_arg->empty()) burn(&finally_arg->front(), finally_arg->size()); });
|
||||
|
||||
if (objectData.size() != keyfileData.size())
|
||||
{
|
||||
|
||||
+1
-1
@@ -373,7 +373,7 @@ typedef unsigned char BOOLEAN;
|
||||
#if defined(_WIN32) && !defined(_UEFI)
|
||||
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); size_t burnc = size; RtlSecureZeroMemory (mem, size); while (burnc--) *burnm++ = 0; } while (0)
|
||||
#else
|
||||
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); int burnc = size; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); size_t burnc = size; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#endif
|
||||
|
||||
#define volatile_memcpy(d,s,size) do { volatile char *destm = (volatile char *)(d); volatile char *srcm = (volatile char *)(s); size_t memc = size; while (memc--) *destm++ = *srcm++; } while (0)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include "Platform/Serializer.h"
|
||||
#include "Platform/Finally.h"
|
||||
#include "Common/SecurityToken.h"
|
||||
#include "Common/EMVToken.h"
|
||||
#include "Crc32.h"
|
||||
@@ -36,6 +37,7 @@ namespace VeraCrypt
|
||||
{
|
||||
// Apply keyfile generated by a security token
|
||||
vector <uint8> keyfileData;
|
||||
finally_do_arg (vector <uint8> *, &keyfileData, { if (!finally_arg->empty()) burn (&finally_arg->front(), finally_arg->size()); });
|
||||
Token::getTokenKeyfile(wstring(Path))->GetKeyfileData(keyfileData);
|
||||
|
||||
if (keyfileData.size() < MinProcessedLength)
|
||||
@@ -57,8 +59,6 @@ namespace VeraCrypt
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
burn(&keyfileData.front(), keyfileData.size());
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user