freeotfegenerateblockiv.c
来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 458 行 · 第 1/2 页
C
458 行
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("ESSIV encrypt failed\n")));
}
}
if (!(NT_SUCCESS(status)))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Failed to ESSIV to form IV.\n")));
}
else
{
// The number of useful bits we can take from the hash
useBitsFromHash = (min(blockIVLength, (encryptLengthBytes * 8)));
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("Number of useful bits from cypher: %d\n"), useBitsFromHash));
// If the block IV is larger than the number of bits the hash returns, ensure that
// the remainder of the block IV is blanked
if (useBitsFromHash < blockIVLength)
{
FREEOTFE_MEMZERO(blockIV, (blockIVLength / 8));
}
// Copy the first 'n' bits of the hash to be the block IV
FREEOTFE_MEMCPY(
blockIV,
&cypherOutput,
(useBitsFromHash / 8) // Divide by 8 to get bytes from bits
);
}
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_EXIT, (TEXT("GenerateblockIV_ESSIV\n")));
return status;
}
// =========================================================================
// Generate block IV
NTSTATUS
GenerateBlockIV(
IN DEVICE_CONTEXT* devContext,
IN LARGE_INTEGER fileOffset, // The offset within the *volume file* where
// the data was obtained from
IN unsigned int blockIVLength, // The size of the required IV (and length of
// "sectorIV"), in bits
OUT unsigned char* blockIV
)
{
NTSTATUS status;
LARGE_INTEGER blockID;
unsigned int useBytes;
unsigned int i;
unsigned int j;
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_ENTER, (TEXT("GenerateBlockIV\n")));
status = STATUS_SUCCESS;
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("Block IV length is: %d\n"), blockIVLength));
// Belt 'n braces - we should never be called if there isn't a fixed blocksize...
if (blockIVLength <= 0)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("IV length requested is <= 0\n")));
status = STATUS_INVALID_PARAMETER;
}
else
{
// Generate the IV...
// Clear down the IV so we have a NULL IV/baseline IV to work from...
FREEOTFE_MEMZERO(
blockIV,
(blockIVLength / 8)
);
// Identify block ID, based on whether block ID zero is the first
// "devContext->EncryptionBlockSize" bytes from the start of the hosting volume
// file or the first "devContext->EncryptionBlockSize" bytes from the start of the
// encrypted partition
if (devContext->VolumeFlags & VOL_FLAGS_SECTOR_ID_ZERO_VOLSTART)
{
// This is correct for default linux - block IDs start, and are relative
// to, the start of the hosting file; though this may be changed by the use
// of the "@" with the linux "losetup" command
blockID.QuadPart = (
fileOffset.QuadPart /
devContext->EncryptionBlockSize
);
}
else
{
// This is correct for FreeOTFE; block IDs start from, and are relative to,
// the start of the encrypted pratition within the volume file
// This means that if the critical data block is removed, and the volume file
// then begins at a 0 byte offset within the volume file, it is still usable
// Note that this driver has no knowledge of the critical data block - that's
// all decoded and handled by the userspace application; this driver only
// dumbly handles encryption/decryption of the encrypted partition - it's
// typically supplied a CRITICAL_DATA_LENGTH offset into the file by the
// userspace application.
blockID.QuadPart = (
(fileOffset.QuadPart - devContext->DataOffset.QuadPart) /
devContext->EncryptionBlockSize
);
} // ELSE PART - if (devContext->VolumeFlags & VOL_FLAGS_SECTOR_ID_ZERO_VOLSTART)
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("Block IV generation method: %d\n"), devContext->SectorIVGenMethod));
switch (devContext->SectorIVGenMethod)
{
case SCTRIVGEN_NONE:
{
// Do nothing - sector IV already zero'd
break;
}
case SCTRIVGEN_32BIT_SECTOR_ID:
{
status = GenerateBlockIV_SectorID(
blockID,
32,
blockIVLength,
blockIV
);
break;
}
case SCTRIVGEN_64BIT_SECTOR_ID:
{
status = GenerateBlockIV_SectorID(
blockID,
64,
blockIVLength,
blockIV
);
break;
}
case SCTRIVGEN_HASH_32BIT_SECTOR_ID:
{
status = GenerateBlockIV_HashedSectorID(
devContext,
blockID,
32,
blockIVLength,
blockIV
);
break;
}
case SCTRIVGEN_HASH_64BIT_SECTOR_ID:
{
status = GenerateBlockIV_HashedSectorID(
devContext,
blockID,
64,
blockIVLength,
blockIV
);
break;
}
case SCTRIVGEN_ESSIV:
{
status = GenerateBlockIV_ESSIV(
devContext,
blockID,
64,
blockIVLength,
blockIV
);
break;
}
default:
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unknown block IV generation method: %d\n"), devContext->SectorIVGenMethod));
status = STATUS_INVALID_PARAMETER;;
}
}
// If we have a per-volume IV, XOR it with IV...
if (NT_SUCCESS(status))
{
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("Block ID: %lld bits\n"), blockID.QuadPart));
for(j = 0; j < (blockIVLength / 8); j++)
{
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Block IV [%.2d]: %.2x\n"), j, blockIV[j]));
}
useBytes = (min(blockIVLength, devContext->VolumeIVLength) / 8);
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("XORing block IV with %d bits of volume IV...\n"), (useBytes * 8)));
for(i = 0; i < useBytes; i++)
{
blockIV[i] ^= devContext->VolumeIV[i];
}
if (useBytes > 0)
{
for(j = 0; j < (blockIVLength / 8); j++)
{
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Actual block IV [%.2d]: %.2x\n"), j, blockIV[j]));
}
}
}
else
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("IV generation failed (status: %d)\n"), status));
}
} // ELSE PART - if (blockIVLength <= 0)
DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_EXIT, (TEXT("GenerateBlockIV\n")));
return status;
}
// =========================================================================
// =========================================================================
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?