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 + -
显示快捷键?