Temporary copy exists in memory after multibyte to wide char conversion

334 views Asked by At

I am trying to convert a secure char string to unicode string. Since I need to handle secure data I ensurd to clear the memory after its usage. I tried following the APIs to unicode conversion.

  • MultiByteToWideChar()
  • A2W()
  • mbstowcs_s()

Conversion to Unicode string worked successfully with above all APIs. I have cleared all the secured data memory after the above operation, including the o/p unicode value. But while dumping the memory after this, a copy of the unicode string remains in memory. I have ensured that all my variables handling the secure data is cleared( by using SecureZeroMemory() API ). I suspect it is temporary copy used by the above APIs. I need the unicode value and need to secure my data. How can I achieve that?

The code snippet is shared below.

CHAR* pszPassword = NULL;
UINT unPlainTextLen  = 0;

// Decrypt the secure data
if( DecryptSecureData( pszPassword, unPlainTextLen))
{
    WCHAR *ptcszPassword_o = new WCHAR[unPlainTextLen + 1];
    ptcszPassword_o[ unPlainTextLen ] = 0;
    size_t unSizeConverted = 0;
    if( 0 == mbstowcs_s( &unSizeConverted, ptcszPassword_o, unPlainTextLen + 1, 
                         reinterpret_cast<CHAR*>( pszPassword ), unPlainTextLen ))
    {   

       // Clear Decrypted o/p buffer
       SecureZeroMemory( pszPassword, unPlainTextLen);
       delete[] pszPassword;

       // Process unicode data ptcszPassword_o

       SecureZeroMemory( ptcszPassword_o, unPlainTextLen  * 2 );
       delete[] pszPassword;
    }              
}
2

There are 2 answers

0
MSalters On

Considering it's just (multi)byte to wide, a WCHAR lookup[256] may be a viable solution. You can init that table using a dummy string passed to MultiByteToWideChar - that's no security leak. Downside: this doesn't work for actual multibyte encodings.

1
aks On

I got a solution to convert to wide character without a temporary copy.

CHAR* pszSecuredData;
// Holds the secured multibyte data in pszSecuredData.

WCHAR* ptcszSecureData = new wchar_t[unSecureDataLength + 1];
swprintf( ptcszSecureData, unSecureDataLength + 1, L"%S", pszSecuredData );