📄 freeotfe4pdacypherdriver.c
字号:
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("About to get cypher details...\n")));
status = CypherGetCypherDetails(
&(BufferIn->CypherGUID),
&CypherDetails
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("Unable to locate requested cypher in driver\n")));
return status;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Cypher details got OK.\n")));
// Input/output buffer must be a multiple of the blocksize
// Output buffer length not explicitly checked, as we already made sure
// that it's big enough to store the input data
// Note: Multiply DataLength by 8 to get bits
if ((CypherDetails.BlockSize > 0) && (((BufferIn->DataLength * 8) % CypherDetails.BlockSize) != 0))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("Length of data IN must be a multiple of the blocksize (bs: %d bits; bufSize: %d bits\n"),
CypherDetails.BlockSize,
(BufferIn->DataLength * 8)));
status = STATUS_INVALID_PARAMETER;
return status;
}
// IV length must = the blocksize
if ((CypherDetails.BlockSize > 0) && (CypherDetails.BlockSize != BufferIn->IVLength))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("The cypher blocksize is greater than 0; the IV length MUST equal the cypher's blocksize (cypher blocksize: %d bits; supplied IV was: %d bits\n"), CypherDetails.BlockSize, BufferIn->IVLength));
status = STATUS_INVALID_PARAMETER;
return status;
}
// KeyLength must = the keysize
if ((CypherDetails.KeySize >= 0) && (CypherDetails.KeySize != BufferIn->KeyLength))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("Keylength must = the cypher's keysize (cypher keysize: %d bits; supplied keysize: %d bits\n"), CypherDetails.KeySize, BufferIn->KeyLength));
status = STATUS_INVALID_PARAMETER;
return status;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Sanity checks OK\n")));
// ASCII representation of "Key".
// Number of chars/nibbles
// +1 to include NULL terminator
// This is included as an optimisation for
// ciphers which use the NIST AES API
keyASCIIBufferLen = ((BufferIn->KeyLength / 4)+1);
keyASCII = FREEOTFE_MEMALLOC(keyASCIIBufferLen);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("keyASCIIBufferLen = %d bytes\n"), keyASCIIBufferLen));
// Convert the data passed in to it's ASCII representation
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("About to convert key data to ASCIIZ rep...\n")));
ConvertDataToASCIIRep(
BufferIn->KeyLength, // In bits
ptrInKey,
keyASCII
);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Converted OK.\n")));
if (NT_SUCCESS(status))
{
// Create a tmp buffer; this is done so that we don't pass both
// the DIOC input and output buffers (the *same* buffer!) to the
// implementation function
// (Also backup dataLength for the same reason)
dataLength = BufferIn->DataLength;
tmpBuffer = FREEOTFE_MEMALLOC(dataLength);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("About to encrypt...\n")));
status = ImpCypherEncryptData(
&BufferIn->CypherGUID,
BufferIn->KeyLength, // In bits
ptrInKey,
keyASCII,
BufferIn->IVLength, // In bits
ptrInIV,
BufferIn->DataLength, // In bytes
ptrInData,
tmpBuffer
);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Done encryption: %d (want status: %d)\n"), status, STATUS_SUCCESS));
FREEOTFE_MEMCPY(&BufferOut->Data, tmpBuffer, dataLength);
SecZeroMemory(tmpBuffer, dataLength);
FREEOTFE_FREE(tmpBuffer);
}
SecZeroMemory(keyASCII, keyASCIIBufferLen);
FREEOTFE_FREE(keyASCII);
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, (TEXT("Encrypt\n")));
return status;
}
// =========================================================================
//
DWORD
CypherDecryptWithASCII(
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
)
{
DWORD status;
DEBUGOUTHASHDRV(DEBUGLEV_ENTER, (TEXT("DecryptWithASCII\n")));
status = ImpCypherDecryptData(
CypherGUID,
KeyLength,
Key,
KeyASCII,
IVLength,
IV,
CyphertextLength,
CyphertextData,
PlaintextData
);
DEBUGOUTHASHDRV(DEBUGLEV_EXIT, (TEXT("DecryptWithASCII\n")));
return status;
}
// =========================================================================
//
DWORD
CypherDecrypt(
IN DWORD BufferInLen,
IN DIOC_CYPHER_DATA_IN* BufferIn,
IN DWORD BufferOutLen,
IN DIOC_CYPHER_DATA_OUT* BufferOut
)
{
DWORD status;
CYPHER CypherDetails;
char* keyASCII;
int keyASCIIBufferLen;
int dataLength;
char* tmpBuffer;
unsigned char* ptrInKey; // Pointer to where the key starts in the input buffer
unsigned char* ptrInIV; // Pointer to where the IV starts in the input buffer
unsigned char* ptrInData; // Pointer to where the data starts in the input buffer
int i;
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, (TEXT("Decrypt\n")));
// Since the variable length members of the input buffer can't be accessed
// directly (their locations vary, depending on the size of earlier members)
// we calculate pointers so they can be accessed easily...
ptrInKey = (char*)&BufferIn->Key;
ptrInIV = ptrInKey + ((BufferIn->KeyLength / 8) * sizeof(BufferIn->Key));
ptrInData = ptrInIV + ((BufferIn->IVLength / 8) * sizeof(BufferIn->IV));
// NOTE: THIS IS ONLY DUMPED OUT IF DEBUG IS NOT ENABLED; ONLY ON
// DEBUG BUILDS.
// Normal release builds cause DEBUGOUTCYPHERDRV to be a NOP, so
// this debug code gets removed
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Key length: %d bits\n"), BufferIn->KeyLength));
for(i = 0; i < (BufferIn->KeyLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Key [%.2d]: %.2x\n"), i, ptrInKey[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- IV length: %d bits\n"), BufferIn->IVLength));
for(i = 0; i < (BufferIn->IVLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- IV [%.2d]: %.2x\n"), i, ptrInIV[i]));
}
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Data length: %d bytes\n"), BufferIn->DataLength));
for(i = 0; i < (BufferIn->DataLength / 8); i++)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Data [%.2d]: %.2x\n"), i, ptrInData[i]));
// Only dump out the first 5 bytes...
if (i >= 5)
{
DEBUGOUTCYPHERDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("----- Data [..]: (Debug output truncated to only show first few bytes)\n")));
break;
}
}
// Sanity checks on the request wrt the cypher
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("About to get cypher details...\n")));
status = CypherGetCypherDetails(
&(BufferIn->CypherGUID),
&CypherDetails
);
if (!(NT_SUCCESS(status)))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("Unable to locate requested cypher in driver\n")));
return status;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Cypher details got OK.\n")));
// Input/output buffer must be a multiple of the blocksize
// Output buffer length not explicitly checked, as we already made sure
// that it's big enough to store the input data
// Note: Multiply DataLength by 8 to get bits
if ((CypherDetails.BlockSize > 0) && (((BufferIn->DataLength * 8) % CypherDetails.BlockSize) != 0))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("Length of data IN must be a multiple of the blocksize (bs: %d bits; bufSize: %d bits\n"),
CypherDetails.BlockSize,
(BufferIn->DataLength * 8)));
status = STATUS_INVALID_PARAMETER;
return status;
}
// IV length must = the blocksize
if ((CypherDetails.BlockSize > 0) && (CypherDetails.BlockSize != BufferIn->IVLength))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("The cypher blocksize is greater than 0; the IV length MUST equal the cypher's blocksize (cypher blocksize: %d bits; supplied IV was: %d bits\n"), CypherDetails.BlockSize, BufferIn->IVLength));
status = STATUS_INVALID_PARAMETER;
return status;
}
// KeyLength must = the keysize
if ((CypherDetails.KeySize >= 0) && (CypherDetails.KeySize != BufferIn->KeyLength))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_ERROR, (TEXT("Keylength must = the cypher's keysize (cypher keysize: %d bits; supplied keysize: %d bits\n"), CypherDetails.KeySize, BufferIn->KeyLength));
status = STATUS_INVALID_PARAMETER;
return status;
}
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Sanity checks OK\n")));
// ASCII representation of "Key".
// Number of chars/nibbles
// +1 to include NULL terminator
// This is included as an optimisation for
// ciphers which use the NIST AES API
keyASCIIBufferLen = ((BufferIn->KeyLength / 4)+1);
keyASCII = FREEOTFE_MEMALLOC(keyASCIIBufferLen);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("keyASCIIBufferLen = %d bytes\n"), keyASCIIBufferLen));
// Convert the data passed in to it's ASCII representation
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("About to convert key data to ASCIIZ rep...\n")));
ConvertDataToASCIIRep(
BufferIn->KeyLength, // In bits
ptrInKey,
keyASCII
);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Converted OK.\n")));
if (NT_SUCCESS(status))
{
// Create a tmp buffer; this is done so that we don't pass both
// the DIOC input and output buffers (the *same* buffer!) to the
// implementation function
// (Also backup dataLength for the same reason)
dataLength = BufferIn->DataLength;
tmpBuffer = FREEOTFE_MEMALLOC(dataLength);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("About to decrypt...\n")));
status = ImpCypherDecryptData(
&BufferIn->CypherGUID,
BufferIn->KeyLength, // In bits
ptrInKey,
keyASCII,
BufferIn->IVLength, // In bits
ptrInIV,
BufferIn->DataLength, // In bytes
ptrInData,
tmpBuffer
);
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Done decryption: %d (want status: %d)\n"), status, STATUS_SUCCESS));
FREEOTFE_MEMCPY(&BufferOut->Data, tmpBuffer, dataLength);
SecZeroMemory(tmpBuffer, dataLength);
FREEOTFE_FREE(tmpBuffer);
}
SecZeroMemory(keyASCII, keyASCIIBufferLen);
FREEOTFE_FREE(keyASCII);
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, (TEXT("Decrypt\n")));
return status;
}
// =========================================================================
DWORD
CypherGetCypherDetails(
IN GUID* CypherGUID,
IN OUT CYPHER* CypherDetails
)
{
NTSTATUS status = STATUS_NOT_FOUND;
CYPHER_DRIVER_INFO tmpDevExt;
unsigned int i;
DEBUGOUTCYPHERDRV(DEBUGLEV_ENTER, (TEXT("GetCypherDetails\n")));
ImpCypherDriverExtDetailsInit(&tmpDevExt);
for (i = 0; i<tmpDevExt.CypherCount; i++)
{
if (IsEqualGUID(&tmpDevExt.CypherDetails[i].CypherGUID, CypherGUID))
{
DEBUGOUTCYPHERDRV(DEBUGLEV_INFO, (TEXT("Located relevant details\n")));
FREEOTFE_MEMCPY(
CypherDetails,
&tmpDevExt.CypherDetails[i],
sizeof(CYPHER)
);
status = STATUS_SUCCESS;
}
}
ImpCypherDriverExtDetailsCleardown(&tmpDevExt);
DEBUGOUTCYPHERDRV(DEBUGLEV_EXIT, (TEXT("GetCypherDetails\n")));
return status;
}
// =========================================================================
// =========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -