freeotfe.c

来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 1,966 行 · 第 1/5 页

C
1,966
字号
                      &fileAttributes
                     );

    if (NT_SUCCESS(status))
        {
        if (DoWrite)
            {
            status = ZwWriteFile(
                                fileHandle,
                                NULL,
                                NULL,
                                NULL,
                                &ioStatusBlock,
                                Data,
                                DataLength,
                                &Offset,
                                NULL
                            );
            }
        else
            {
            status = ZwReadFile(
                                fileHandle,
                                NULL,
                                NULL,
                                NULL,
                                &ioStatusBlock,
                                Data,
                                DataLength, 
                                &Offset,
                                NULL
                            );
            }
        DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Status: %d; wanted: %d.\n", status, STATUS_SUCCESS));
        DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Read/written: %d bytes (only valid if status is success).\n", ioStatusBlock.Information));
        if (!(NT_SUCCESS(status)))
            {
            DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Unable to read/write raw (%d %d).\n", status, ioStatusBlock.Status));
            status = STATUS_INVALID_PARAMETER;
            }
        else if (ioStatusBlock.Information != DataLength)
            {
            DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("Failed to read/write all data. Transferred: %d bytes; expected: %d bytes.\n", ioStatusBlock.Information, DataLength));
            status = STATUS_INVALID_PARAMETER;
            }
    

        // Return value ignored
        FileClose(
                  &fileHandle,
                  fileAttributesStored,
                  &fileAttributes,
                  &ioStatusBlock
                 );

        }

    // Return value ignored
    ClientSecurityDestroy(&ClientContext);

    DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("SetGetRawUnicode\n"));

    return status;
}


// =========================================================================
// Derive a key
NTSTATUS
IOCTL_FreeOTFEIOCTL_DeriveKey(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_DERIVE_KEY_IN DIOCBufferIn;
    PDIOC_DERIVE_KEY_OUT DIOCBufferOut;
    unsigned char* tmpOutput;
    int tmpLengthBits;  // In *bits*
    int userBufferSizeBytes;  // In *bytes*
    unsigned int useBits;  // In *bits*
    int lengthWanted;  // In *bits*
    unsigned int i;

    DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEIOCTL_DeriveKey\n"));

    status = STATUS_SUCCESS;

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    DIOCBufferIn = (PDIOC_DERIVE_KEY_IN)Irp->AssociatedIrp.SystemBuffer;
    DIOCBufferOut = (PDIOC_DERIVE_KEY_OUT)Irp->AssociatedIrp.SystemBuffer;

    // Check size of INPUT buffer
    // Minimum check...
    // (Done first in order to ensure that we can later access length related
    // members for actual check)
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_DERIVE_KEY_IN) 
              - sizeof(DIOCBufferIn->Password)
              - sizeof(DIOCBufferIn->Salt)
            )
        )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
            (
             sizeof(DIOC_DERIVE_KEY_IN)
              - sizeof(DIOCBufferIn->Password)
              - sizeof(DIOCBufferIn->Salt)
            ),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }
    // Actual check...
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_DERIVE_KEY_IN)
              - sizeof(DIOCBufferIn->Password)
              - sizeof(DIOCBufferIn->Salt)
              + (DIOCBufferIn->PasswordLength / 8)
              + (DIOCBufferIn->SaltLength / 8)
            )
        )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
            (
             sizeof(DIOC_DERIVE_KEY_IN)
              - sizeof(DIOCBufferIn->Password)
              - sizeof(DIOCBufferIn->Salt)
              + (DIOCBufferIn->PasswordLength / 8)
              + (DIOCBufferIn->SaltLength / 8)
            ),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }


    // Check size of OUTPUT buffer
    // Minimum check...
    // (Done first in order to ensure that we can later access length related
    // members for actual check)
    if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof(DIOC_DERIVE_KEY_OUT)-sizeof(DIOCBufferOut->DerivedKey))
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect min: %d; got: %d)\n",
            sizeof(DIOC_DERIVE_KEY_OUT)-sizeof(DIOCBufferOut->DerivedKey),
            irpSp->Parameters.DeviceIoControl.OutputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }

        

    // Request valid so far, process...    


    // We have to allocate a buffer to hold the output, before it can be copied
    // out to the output buffer; otherwise, the input buffer gets garbled as
    // data is written to the output buffer

    // Match the user's buffer; if it's too small, the operation will kick
    // it out
    // This calculates the size of the variable part of the struct
    // Yes, this should be correct: The total size of the user's output buffer,
    // less the size of the struct - but then plus the size of
    // the variable parts reserved within the buffer
    userBufferSizeBytes = (irpSp->Parameters.DeviceIoControl.OutputBufferLength) - 
                          sizeof(DIOCBufferOut) +
                          sizeof(DIOCBufferOut->DerivedKey);
    tmpOutput = ExAllocatePool(
                                NonPagedPool,
                                userBufferSizeBytes
                               ); 

    // The size of the buffer in bits; the algorithm will read this value, then
    // overwrite it with the actual size of the output (in bits)
    tmpLengthBits = (userBufferSizeBytes * 8);

    DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Allocated output buffer for: %d bits\n", tmpLengthBits));
    
    DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("About to process...\n"));


    // This call runs the correct algorithm and generates the output
    if (DIOCBufferIn->LengthWanted == 0)
        {
        // Optimisation - if the user wants a zero length output, don't
        // bother processing, just return zero length output.
        DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("Zero length output requested; returning nothing\n"));
        tmpLengthBits = 0;
        status = STATUS_SUCCESS;
        }
    else
        {
        status = DeriveKey(
                    DIOCBufferIn->KDFAlgorithm,
                    DIOCBufferIn->HashDeviceName,
                    DIOCBufferIn->HashGUID,
                    DIOCBufferIn->CypherDeviceName,
                    DIOCBufferIn->CypherGUID,
                    DIOCBufferIn->Iterations,
                    DIOCBufferIn->LengthWanted,
                    DIOCBufferIn->PasswordLength,  // In bits
                    (unsigned char*)&DIOCBufferIn->Password,  // Variable length
                    DIOCBufferIn->SaltLength,  // In bits
                    // This may seem a little weird, but is required as the
                    // position of the salt within the struct is variable
                    &DIOCBufferIn->Password[(DIOCBufferIn->PasswordLength / 8)],  // Variable length

                    &tmpLengthBits,  // In bits
                    (unsigned char*)tmpOutput  // Variable length
                    );
        }

    DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("DK Done with status: %d (want status: %d)\n", status, STATUS_SUCCESS));
    if (NT_SUCCESS(status)) 
        {
        DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("tmp buffer was: %d bits, output was %d bits\n", (userBufferSizeBytes * 8), tmpLengthBits));


        // Preserve input buffer value, to ensure we don't overwrite it with
        // the output buffer
        lengthWanted = DIOCBufferIn->LengthWanted;


        // Actual check...

        // Ensure output DIOC butter is large enough to store the output
        // Note that we can't carry out this check until we've created the
        // output value, in case the algorithm used produces variable length
        // output

        // If the user specified an output length, we only use those bits
        if (lengthWanted >= 0) 
            {
            if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
                    sizeof(DIOC_DERIVE_KEY_OUT)+(lengthWanted/8)-sizeof(DIOCBufferOut->DerivedKey))
                {
                DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect actual: %d; got: %d)\n",
                    sizeof(DIOC_DERIVE_KEY_OUT)+(lengthWanted/8)-sizeof(DIOCBufferOut->DerivedKey),
                    irpSp->Parameters.DeviceIoControl.OutputBufferLength
                    ));
                status = STATUS_INVALID_BUFFER_SIZE;
                }
            else
                {
                // If the algorithm doens't generate enough bits, we right-pad
                // with NULLs
                if (lengthWanted > tmpLengthBits)
                    {
                    // Cleardown the buffer beyond the output
                    RtlZeroMemory(
                                &DIOCBufferOut->DerivedKey,
                                (lengthWanted / 8)
                                );

                    useBits = tmpLengthBits;
                    }
                else
                    {
                    useBits = lengthWanted;
                    }
                RtlCopyMemory(&DIOCBufferOut->DerivedKey, tmpOutput, (useBits / 8));
                DIOCBufferOut->DerivedKeyLength = lengthWanted;
                }
            }
        else
            // User didn't specify an output length - we use the entire
            // algorithm's output
            {
            if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
                    sizeof(DIOC_DERIVE_KEY_OUT)+(tmpLengthBits/8)-sizeof(DIOCBufferOut->DerivedKey))
                {
                DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("outBuffer size wrong size (expect actual: %d; got: %d)\n",
                    sizeof(DIOC_DERIVE_KEY_OUT)+(tmpLengthBits/8)-sizeof(DIOCBufferOut->DerivedKey),
                    irpSp->Parameters.DeviceIoControl.OutputBufferLength
                    ));
                status = STATUS_INVALID_BUFFER_SIZE;
                }
            else
                {
                RtlCopyMemory(&DIOCBufferOut->DerivedKey, tmpOutput, (tmpLengthBits / 8));
                DIOCBufferOut->DerivedKeyLength = tmpLengthBits;
                }
            }

        Irp->IoStatus.Information = sizeof(DIOC_DERIVE_KEY_OUT)+(DIOCBufferOut->DerivedKeyLength/8)-sizeof(DIOCBufferOut->DerivedKey);
        }
    else
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("FAILED"));
        }

    SecZeroMemory(tmpOutput, userBufferSizeBytes);
    ExFreePool(tmpOutput);


    if (NT_SUCCESS(status)) 
        {
        // NOTE: THE KEY IS ONLY DUMPED OUT IF DEBUG IS ENABLED; ONLY ON
        //       DEBUG BUILDS.
        //       Normal release builds cause DEBUGOUTMAINDRV to be a NOP, so
        //       this debug code gets removed
        DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("----- DerivedKey length: %d bits\n", DIOCBufferOut->DerivedKeyLength));
        for(i = 0; i < (DIOCBufferOut->DerivedKeyLength / 8); i++)
            { 
            DEBUGOUTMAINDRV(DEBUGLEV_INFO, ("----- DerivedKey [%.2d]: %.2x\n", i, DIOCBufferOut->DerivedKey[i]));
            }                                
        }



    DEBUGOUTMAINDRV(DEBUGLEV_EXIT, ("IOCTL_FreeOTFEIOCTL_DeriveKey\n"));

    return status;
}

    
// =========================================================================
// Generate a MAC
NTSTATUS
IOCTL_FreeOTFEIOCTL_GenerateMAC(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    NTSTATUS status;
    PIO_STACK_LOCATION irpSp;
    PDIOC_GENERATE_MAC_IN DIOCBufferIn;
    PDIOC_GENERATE_MAC_OUT DIOCBufferOut;
    unsigned char* tmpOutput;
    int tmpLengthBits;  // In *bits*
    int userBufferSizeBytes;  // In *bytes*
    unsigned int useBits;  // In *bits*
    int lengthWanted;  // In *bits*
    unsigned int i;

    DEBUGOUTMAINDRV(DEBUGLEV_ENTER, ("IOCTL_FreeOTFEIOCTL_GenerateMAC\n"));

    status = STATUS_SUCCESS;

    irpSp = IoGetCurrentIrpStackLocation(Irp);

    DIOCBufferIn = (PDIOC_GENERATE_MAC_IN)Irp->AssociatedIrp.SystemBuffer;
    DIOCBufferOut = (PDIOC_GENERATE_MAC_OUT)Irp->AssociatedIrp.SystemBuffer;

    // Check size of INPUT buffer
    // Minimum check...
    // (Done first in order to ensure that we can later access length related
    // members for actual check)
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_GENERATE_MAC_IN) 
              - sizeof(DIOCBufferIn->Key)
              - sizeof(DIOCBufferIn->Data)
            )
        )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect min: %d; got: %d)\n",
            (
             sizeof(DIOC_GENERATE_MAC_IN) 
              - sizeof(DIOCBufferIn->Key)
              - sizeof(DIOCBufferIn->Data)
            ),
            irpSp->Parameters.DeviceIoControl.InputBufferLength
            ));
        status = STATUS_INVALID_BUFFER_SIZE;
        return status;            
        }
    // Actual check...
    if (irpSp->Parameters.DeviceIoControl.InputBufferLength <
            (
             sizeof(DIOC_GENERATE_MAC_IN) 
              - sizeof(DIOCBufferIn->Key)
              - sizeof(DIOCBufferIn->Data)
              + (DIOCBufferIn->KeyLength / 8)
              + (DIOCBufferIn->DataLength / 8)
            )
        )
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, ("inBuffer size wrong size (expect actual: %d; got: %d)\n",
            (
             sizeof(DIOC_GEN

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?