freeotfecypherdes.c

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

C
400
字号
// Description: 
// By Sarah Dean
// Email: sdean12@sdean12.org
// WWW:   http://www.FreeOTFE.org/
//
// -----------------------------------------------------------------------------
//

#ifndef WINCE
#include <ntddk.h>
#endif

#include "FreeOTFECypherDES.h"

#include "FreeOTFECypherImpl.h"
#include "FreeOTFECypherAPICommon.h"

#ifdef WINCE
#include "FreeOTFE4PDACypherDriver.h"  // Required for DRIVER_CYPHER_VERSION
#else
#include "FreeOTFECypherDriver.h"  // Required for DRIVER_CYPHER_VERSION
#endif

#include "FreeOTFEPlatform.h"
#include "FreeOTFEDebug.h"
#include "FreeOTFElib.h"


// Include libtomcrypt DES library...
//#define CBC 1
//#include <mycrypt.h>
//#include <mycrypt_cipher.h>
#include <mycrypt_custom.h>


// =========================================================================
// Cypher driver init function
// driverInfo - The structure to be initialized
NTSTATUS
ImpCypherDriverExtDetailsInit(
    IN OUT CYPHER_DRIVER_INFO* driverInfo
)
{
    NTSTATUS status = STATUS_SUCCESS;
    int idx = -1;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDriverExtDetailsInit\n")));


    // -- POPULATE DRIVER IDENTIFICATION --
    FREEOTFE_MEMZERO(driverInfo->DriverTitle, sizeof(driverInfo->DriverTitle));
    FREEOTFE_MEMCPY(
                  driverInfo->DriverTitle,
                  DRIVER_TITLE,
                  strlen(DRIVER_TITLE)
                 );

    driverInfo->DriverGUID = DRIVER_GUID;
    driverInfo->DriverVersionID = DRIVER_CYPHER_VERSION;


    // -- POPULATE cyphers SUPPORTED --
    driverInfo->CypherDetails = FREEOTFE_MEMALLOC((sizeof(CYPHER) * CYPHERS_SUPPORTED));    

    driverInfo->CypherCount = CYPHERS_SUPPORTED;


    // -- DES --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_DES,
                  strlen(DRIVER_CIPHER_TITLE_DES)
                 );

    driverInfo->CypherDetails[idx].Mode       = CYPHER_MODE_CBC;
    driverInfo->CypherDetails[idx].KeySize    = (des_desc.max_key_length * 8);
    driverInfo->CypherDetails[idx].BlockSize  = (des_desc.block_length * 8);
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_DES;

    // -- 3DES --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_3DES,
                  strlen(DRIVER_CIPHER_TITLE_3DES)
                 );

    driverInfo->CypherDetails[idx].Mode       = CYPHER_MODE_CBC;
    driverInfo->CypherDetails[idx].KeySize    = (des3_desc.max_key_length * 8);
    driverInfo->CypherDetails[idx].BlockSize  = (des3_desc.block_length * 8);
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_3DES;


    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDriverExtDetailsInit\n")));

    return status;
}


// =========================================================================
// Cypher driver cleardown function
// driverInfo - The structure to be cleared down
NTSTATUS
ImpCypherDriverExtDetailsCleardown(    
    IN OUT CYPHER_DRIVER_INFO* driverInfo
)
{
    NTSTATUS status = STATUS_SUCCESS;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDriverExtDetailsCleardown\n")));

    if (driverInfo->CypherDetails != NULL)
        {
        FREEOTFE_FREE(driverInfo->CypherDetails);
        }

    driverInfo->CypherDetails = NULL;
    driverInfo->CypherCount = 0;


    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDriverExtDetailsCleardown\n")));

    return status;
}


// =========================================================================
// Encryption function
// Note: CyphertextLength must be set to the size of the CyphertextData buffer on
//       entry; on exit, this will be set to the size of the buffer used.
NTSTATUS
ImpCypherEncryptData(
    IN      GUID* CypherGUID,
    IN      int KeyLength,  // In bits
    IN      char *Key,
    IN      char *KeyASCII,  // ASCII representation of "Key"
    IN      int IVLength,  // In bits
    IN      char *IV,
    IN      int PlaintextLength,  // In bytes
    IN      char *PlaintextData,
    OUT     char *CyphertextData
)
{
    NTSTATUS status = STATUS_SUCCESS;
    // libtomcrypt can't handle NULL IVs in CBC mode - it ASSERTs that IV != NULL
    char ltcNullIV[FREEOTFE_MAX_CYPHER_BLOCKSIZE];
    int cipher;
    unsigned int i;
    symmetric_CBC *cbc;
    int errnum;
    unsigned char* inBufPtr;
    unsigned char* outBufPtr;
    unsigned int x;
    unsigned int blockLength;


    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherEncryptData\n")));


    cbc = FREEOTFE_MEMALLOC(sizeof(symmetric_CBC));    
    FREEOTFE_MEMZERO(cbc, sizeof(symmetric_CBC));

    if (IsEqualGUID(&CIPHER_GUID_DES, CypherGUID))
        {
    	status = InitLTCDESCypher(&cipher);
        blockLength = des_desc.block_length;
        }
    else if (IsEqualGUID(&CIPHER_GUID_3DES, CypherGUID))
        {
	status = InitLTC3DESCypher(&cipher);
        blockLength = des3_desc.block_length;
        }
    else
        {
    	DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unsupported cipher GUID passed in.\n")));
        status = STATUS_INVALID_PARAMETER;
        }

    // libtomcrypt can't handle NULL IVs in CBC mode - it ASSERTs that IV != NULL
    if ( (IVLength == 0) || (IV == NULL) )
        {
        FREEOTFE_MEMZERO(&ltcNullIV, sizeof(ltcNullIV));
        IV = (char*)&ltcNullIV;
        }

	if NT_SUCCESS(status)
		{
	    // Start a CBC session
        if ((errnum = cbc_start(cipher, IV, Key, (KeyLength/8), 0, cbc)) != CRYPT_OK)
            {
			status = STATUS_UNSUCCESSFUL;
			DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to start CBC session (errnum: %d)\n"), errnum));
            }
		}

    if NT_SUCCESS(status)
        {
        x = (unsigned int)(int)(PlaintextLength / blockLength);
		inBufPtr = PlaintextData;
		outBufPtr = CyphertextData;
        for (i = 0; i < x; i++)
            {
            if ((errnum = cbc_encrypt(inBufPtr, outBufPtr, cbc)) != CRYPT_OK)
                {
                DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to encrypt/decrypt block (errnum: %d)\n"), errnum));
                status = STATUS_UNSUCCESSFUL;
                } 
                
            inBufPtr  += blockLength;
            outBufPtr += blockLength;
            }
		}

    SecZeroMemory(cbc, sizeof(symmetric_CBC));
    FREEOTFE_FREE(cbc);


    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherEncryptData\n")));

    return status;
}


// =========================================================================
// Decryption function
// Note: PlaintextLength must be set to the size of the PlaintextData buffer on
//       entry; on exit, this will be set to the size of the buffer used.
NTSTATUS
ImpCypherDecryptData(
    IN      GUID* CypherGUID,
    IN      int KeyLength,  // In bits
    IN      char *Key,
    IN      char *KeyASCII,  // ASCII representation of "Key"
    IN      int IVLength,  // In bits
    IN      char *IV,
    IN      int CyphertextLength,  // In bytes
    IN      char *CyphertextData,
    OUT     char *PlaintextData
)
{
    NTSTATUS status = STATUS_SUCCESS;
    // libtomcrypt can't handle NULL IVs in CBC mode - it ASSERTs that IV != NULL
    char ltcNullIV[FREEOTFE_MAX_CYPHER_BLOCKSIZE];
    int cipher;
    unsigned int i;
    symmetric_CBC *cbc;
    int errnum;
    unsigned char* inBufPtr;
    unsigned char* outBufPtr;
    unsigned int x;
    unsigned int blockLength;


    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDecryptData\n")));


    cbc = FREEOTFE_MEMALLOC(sizeof(symmetric_CBC));    
    FREEOTFE_MEMZERO(cbc, sizeof(symmetric_CBC));

    if (IsEqualGUID(&CIPHER_GUID_DES, CypherGUID))
        {
	status = InitLTCDESCypher(&cipher);
        blockLength = des_desc.block_length;
        }
    else if (IsEqualGUID(&CIPHER_GUID_3DES, CypherGUID))
        {
	status = InitLTC3DESCypher(&cipher);
        blockLength = des3_desc.block_length;
        }
    else
        {
	DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unsupported cipher GUID passed in.\n")));
        status = STATUS_INVALID_PARAMETER;
        }

    // libtomcrypt can't handle NULL IVs in CBC mode - it ASSERTs that IV != NULL
    if ( (IVLength == 0) || (IV == NULL) )
        {
        FREEOTFE_MEMZERO(&ltcNullIV, sizeof(ltcNullIV));
        IV = (char*)&ltcNullIV;
        }

	if NT_SUCCESS(status)
		{
	    // Start a CBC session
        if ((errnum = cbc_start(cipher, IV, Key, (KeyLength/8), 0, cbc)) != CRYPT_OK)
            {
			status = STATUS_UNSUCCESSFUL;
			DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to start CBC session (errnum: %d)\n"), errnum));
            }
		}

    if NT_SUCCESS(status)
        {
        x = (unsigned int)(int)(CyphertextLength / blockLength);
		inBufPtr = CyphertextData;
		outBufPtr = PlaintextData;
        for (i = 0; i < x; i++)
            {
            if ((errnum = cbc_decrypt(inBufPtr, outBufPtr, cbc)) != CRYPT_OK)
                {
                DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to encrypt/decrypt block (errnum: %d)\n"), errnum));
                status = STATUS_UNSUCCESSFUL;
                } 
                
            inBufPtr  += blockLength;
            outBufPtr += blockLength;
            }
		}

    SecZeroMemory(cbc, sizeof(symmetric_CBC));
    FREEOTFE_FREE(cbc);


    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDecryptData\n")));

    return status;
}


// =========================================================================
// Initialize libtomcrypt DES cypher
NTSTATUS
InitLTCDESCypher(
    OUT  int *cipher
)
{
	NTSTATUS status = STATUS_CRYPTO_SYSTEM_INVALID;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("InitLTCDESCypher\n")));

    // Initialize cipher
    *cipher = register_cipher(&des_desc);
    if (*cipher == -1)
        {
	    DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Could not register cipher\n")));
        }
    else
        {    
        *cipher = find_cipher("des");
        if (*cipher == -1)
            {
      	    DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Could not find cipher\n")));
            }
		else
			{
			status = STATUS_SUCCESS;
			}
        }

    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("InitLTCDESCypher\n")));

	return status;
}

// =========================================================================
// Initialize libtomcrypt 3DES cypher
NTSTATUS
InitLTC3DESCypher(
    OUT  int *cipher
)
{
	NTSTATUS status = STATUS_CRYPTO_SYSTEM_INVALID;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("InitLTC3DESCypher\n")));

    // Initialize cipher
    *cipher = register_cipher(&des3_desc);
    if (*cipher == -1)
        {
	    DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Could not register cipher\n")));
        }
    else
        {    
        *cipher = find_cipher("3des");
        if (*cipher == -1)
            {
      	    DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Could not find cipher\n")));
            }
		else
			{
			status = STATUS_SUCCESS;
			}
        }

    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("InitLTC3DESCypher\n")));

	return status;
}


// =========================================================================
// =========================================================================

⌨️ 快捷键说明

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