Windows: enhancement to RAM encryption
- use a more standard-looking memory value tag instead of fully random one that will look suspicious and outstanding - If we fail to allocate 1MiB for derivation area, we device the size by two in a loop until we succeed. This is better than falling back directly to 8KiB size - Better method to derive actual encryption key: instead of simply duplicating 128bit key value, we combine a xor addition and self-encryption to build a 256-bit key - use both encID and pbKeyDerivationArea to derive IV for encryption and not only endID
This commit is contained in:
parent
5192eac233
commit
c0f8179f2a
|
@ -1305,8 +1305,8 @@ BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback)
|
|||
ChaCha20RngCtx ctx;
|
||||
byte pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ];
|
||||
#ifdef TC_WINDOWS_DRIVER
|
||||
byte i, tagLength;
|
||||
|
||||
byte i;
|
||||
char randomStr[4];
|
||||
Dump ("InitializeSecurityParameters BEGIN\n");
|
||||
#endif
|
||||
|
||||
|
@ -1315,28 +1315,57 @@ BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback)
|
|||
ChaCha20RngInit (&ctx, pbSeed, rngCallback, 0);
|
||||
|
||||
#ifdef TC_WINDOWS_DRIVER
|
||||
/* generate random tag length between 1 and 4 */
|
||||
tagLength = GetRandomIndex (&ctx, 4) + 1;
|
||||
|
||||
/* generate random value for tag:
|
||||
* Each ASCII character in the tag must be a value in the range 0x20 (space) to 0x7E (tilde)
|
||||
* So we have 95 possibility
|
||||
/* Generate random value for tag that is similar to pool tag values used by Windows kernel.
|
||||
* Fully random tag would be too suspicious and outstanding.
|
||||
* First character is always a capital letter.
|
||||
* Second character is a letter, lowercase or uppercase.
|
||||
* Third character is a letter, lowercase or uppercase.
|
||||
* Fourth character is a letter or a digit.
|
||||
*/
|
||||
|
||||
/* 1. First character (Capital Letter) */
|
||||
randomStr[0] = 'A' + GetRandomIndex(&ctx, 26);
|
||||
|
||||
/* 2. Second character (Letter) */
|
||||
i = GetRandomIndex(&ctx, 52);
|
||||
if (i < 26)
|
||||
randomStr[1] = 'A' + i;
|
||||
else
|
||||
randomStr[1] = 'a' + (i - 26);
|
||||
|
||||
/* 3. Third character (Letter) */
|
||||
i = GetRandomIndex(&ctx, 52);
|
||||
if (i < 26)
|
||||
randomStr[2] = 'A' + i;
|
||||
else
|
||||
randomStr[2] = 'a' + (i - 26);
|
||||
|
||||
/* 4. Fourth character (Letter or Digit) */
|
||||
i = GetRandomIndex(&ctx, 62);
|
||||
if (i < 26)
|
||||
randomStr[3] = 'A' + i;
|
||||
else if (i < 52)
|
||||
randomStr[3] = 'a' + (i - 26);
|
||||
else
|
||||
randomStr[3] = '0' + (i - 52);
|
||||
|
||||
/* combine all characters in reverse order as explained in MSDN */
|
||||
AllocTag = 0;
|
||||
for (i = 0; i < tagLength; i++)
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
AllocTag = (AllocTag << 8) + (((ULONG) GetRandomIndex (&ctx, 95)) + 0x20);
|
||||
AllocTag = (AllocTag << 8) + randomStr[3-i];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
cbKeyDerivationArea = 1024 * 1024;
|
||||
pbKeyDerivationArea = (byte*) TCalloc(cbKeyDerivationArea);
|
||||
if (!pbKeyDerivationArea)
|
||||
do
|
||||
{
|
||||
cbKeyDerivationArea = 2 * PAGE_SIZE;
|
||||
pbKeyDerivationArea = (byte*) TCalloc(cbKeyDerivationArea);
|
||||
}
|
||||
if (!pbKeyDerivationArea)
|
||||
cbKeyDerivationArea >>= 1;
|
||||
} while (!pbKeyDerivationArea && (cbKeyDerivationArea >= (2*PAGE_SIZE)));
|
||||
|
||||
if (!pbKeyDerivationArea)
|
||||
{
|
||||
|
@ -1357,7 +1386,7 @@ BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback)
|
|||
FAST_ERASE64 (pbSeed, sizeof (pbSeed));
|
||||
burn (&ctx, sizeof (ctx));
|
||||
#ifdef TC_WINDOWS_DRIVER
|
||||
burn (&tagLength, 1);
|
||||
burn (randomStr, sizeof(randomStr));
|
||||
|
||||
Dump ("InitializeSecurityParameters return=TRUE END\n");
|
||||
#endif
|
||||
|
@ -1402,11 +1431,20 @@ void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData,
|
|||
hashLow = t1ha2_atonce128(&hashHigh, pbKeyDerivationArea, cbKeyDerivationArea, hashSeed);
|
||||
|
||||
/* set the key to the hash result */
|
||||
pbKey[0] = pbKey[2] = hashLow;
|
||||
pbKey[1] = pbKey[3] = hashHigh;
|
||||
pbKey[0] = hashLow;
|
||||
pbKey[1] = hashHigh;
|
||||
/* we now have a 128-bit key and we will expand it to 256-bit by using ChaCha12 cipher */
|
||||
/* first we need to generate a the other 128-bit half of the key */
|
||||
pbKey[2] = hashLow ^ hashHigh;
|
||||
pbKey[3] = hashLow + hashHigh;
|
||||
|
||||
/* Initialize ChaCha12 cipher */
|
||||
cipherIV = encID ^ CipherIVMask;
|
||||
ChaCha256Init (&ctx, (unsigned char*) pbKey, (unsigned char*) &hashSeed, 12);
|
||||
/* encrypt the key by itself */
|
||||
ChaCha256Encrypt (&ctx, (unsigned char*) pbKey, sizeof(pbKey), (unsigned char*) pbKey);
|
||||
|
||||
/* Initialize ChaCha12 cipher */
|
||||
cipherIV = (((uint64) pbKeyDerivationArea) + encID) ^ CipherIVMask;
|
||||
ChaCha256Init (&ctx, (unsigned char*) pbKey, (unsigned char*) &cipherIV, 12);
|
||||
|
||||
ChaCha256Encrypt (&ctx, pbData, cbData, pbData);
|
||||
|
|
Loading…
Reference in New Issue