Adding Add/Remove Padding for PKCS7

This commit is contained in:
Yuval Harpaz 2021-07-06 20:20:23 +03:00
Родитель 715bb3a906
Коммит 5707111a68
3 изменённых файлов: 11 добавлений и 8 удалений

Просмотреть файл

@ -3078,10 +3078,14 @@ SymCryptPaddingPkcs7Remove(
// Even if an error is returned, the pbDst buffer may or may not contain data from the message.
// Callers should wipe the buffer even if an error is returned.
//
// In case that the padding is invalid and the output buffer is too small, both the
// errors above are detected, but SYMCRYPT_INVALID_ARGUMENT gets precedence over
// SYMCRYPT_BUFFER_TOO_SMALL and the returned value will be SYMCRYPT_INVALID_ARGUMENT.
//
// Note: Removal of PKCS7 padding is extremely sensitive to side channels.
// For example, if a message is encrypted with AES-CBC and the attacker can modify
// the ciphertext and then determine whether a padding error occurrs during decryption,
// then the attacker can use the presence or absense of the error to decrypt the message itself.
// then the attacker can use the presence or absence of the error to decrypt the message itself.
// This function takes great care not to reveal whether an error occurred, and hides
// the size of the unpadded message. This is even true when writing to pbDst. If cbDst is large
// enough, the code will write cbSrc-1 bytes to pbDst, using masking to only update the bytes of the

Просмотреть файл

@ -45,7 +45,7 @@ SymCryptPaddingPkcs7Add(
// perform the padding
//
// cbSrc must be greater than zero. memcpy(,,0) is not defined!
// cbSrc must be greater than zero. memcpy(pbDst, NULL, 0) is not defined!
if (pbDst != pbSrc && cbSrc > 0)
{
memcpy(pbDst, pbSrc, cbSrc);
@ -154,6 +154,7 @@ cleanup:
*pcbResult = cbResult;
// Update scError with the two error masks.
// SYMCRYPT_INVALID_ARGUMENT gets precedence over SYMCRYPT_BUFFER_TOO_SMALL
scError ^= mBufferSizeError & (scError ^ SYMCRYPT_BUFFER_TOO_SMALL);
scError ^= mPaddingError & (scError ^ SYMCRYPT_INVALID_ARGUMENT);

Просмотреть файл

@ -145,12 +145,10 @@ testScsMapUint32()
GENRANDOM(&u32To2, sizeof(u32To2));
GENRANDOM(&u32To3, sizeof(u32To3));
SYMCRYPT_UINT32_MAP map1 = { u32From1, u32To1 };
SYMCRYPT_UINT32_MAP map2 = { u32From2, u32To2 };
SYMCRYPT_UINT32_MAP map3 = { u32From2, u32To3 }; // multiple map entries may have the same 'from'
SYMCRYPT_UINT32_MAP pMap[2] = { map1, map2 };
SYMCRYPT_UINT32_MAP pMap[3] = {
{ u32From1, u32To1 },
{ u32From2, u32To2 },
{ u32From2, u32To3 } }; // multiple map entries may have the same 'from'
//
// Case 1: u32Input matches the 'from' field of only one entry