📄 cfbimpl.c
字号:
/* Copyright 2003-2004, Voltage Security, all rights reserved.
*/
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "cipher.h"
#include "block.h"
#include "cfb.h"
#include "errorctx.h"
int CFBEncryptInit (
VoltAlgorithmObject *algObj,
VoltKeyObject *keyObj
)
{
int status;
VoltLibCtx *libCtx = (VoltLibCtx *)(algObj->voltObject.libraryCtx);
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Copy the initVector.
*/
Z2Memcpy (
cfbCtx->currentVector, cfbCtx->feedCtx.initVector,
cfbCtx->feedCtx.blockSize);
cfbCtx->xorUsed = cfbCtx->feedCtx.blockSize;
/* Call the underlying algorithm's Init.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = cfbCtx->AlgEncryptInit (algObj, keyObj);
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, algObj->voltObject.libraryCtx, status, 0, fnctLine,
"CFBEncryptInit", (char *)0)
return (status);
}
int CFBEncryptUpdateBlock (
VoltAlgorithmObject *algObj,
VtRandomObject random,
unsigned char *dataToEncrypt,
unsigned int dataToEncryptLen,
unsigned char *encryptedData
)
{
unsigned int index, dataLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(algObj->voltObject.libraryCtx);
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
/* If we have some unused bits in the XOR vector, use them.
*/
if (cfbCtx->xorUsed < cfbCtx->feedCtx.blockSize)
{
/* Are there enough dataToEncrypt bytes to finish out the block of
* XOR bytes we have available?
*/
dataLen = cfbCtx->feedCtx.blockSize - cfbCtx->xorUsed;
if (dataToEncryptLen < dataLen)
dataLen = dataToEncryptLen;
for (index = cfbCtx->xorUsed; index < (cfbCtx->xorUsed + dataLen) ; ++index)
{
/* Encrypted data is the input XOR'd with a byte from the XOR
* vector.
*/
*encryptedData = *dataToEncrypt ^ cfbCtx->feedCtx.xorVector[index];
/* The ciphertext will be used to generate the next XOR vector,
* so save it.
*/
cfbCtx->currentVector[index] = *encryptedData;
dataToEncrypt++;
encryptedData++;
}
dataToEncryptLen -= dataLen;
cfbCtx->xorUsed += dataLen;
}
/* So long as we have blocks, operate on them.
*/
while (dataToEncryptLen >= cfbCtx->feedCtx.blockSize)
{
/* Encrypt the currentVector to get the XOR vector.
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
/* XOR each byte of input with the XOR vector. This will be the
* ciphertext, which is also the next vector to encrypt.
*/
for (index = 0; index < cfbCtx->feedCtx.blockSize; ++index)
{
cfbCtx->currentVector[index] =
cfbCtx->feedCtx.xorVector[index] ^ dataToEncrypt[index];
}
/* Copy the data to the output buffer.
*/
Z2Memcpy (encryptedData, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize);
dataToEncrypt += cfbCtx->feedCtx.blockSize;
encryptedData += cfbCtx->feedCtx.blockSize;
dataToEncryptLen -= cfbCtx->feedCtx.blockSize;
}
/* After processing full blocks, if there's no more input, we're done.
*/
if (dataToEncryptLen == 0)
return (0);
/* We have some leftovers, create the XOR vector.
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
for (index = 0; index < dataToEncryptLen; ++index)
{
encryptedData[index] =
dataToEncrypt[index] ^ cfbCtx->feedCtx.xorVector[index];
/* The ciphertext will be used to generate the next XOR vector,
* so save it.
*/
cfbCtx->currentVector[index] = encryptedData[index];
}
cfbCtx->xorUsed = dataToEncryptLen;
return (0);
}
int CFBEncryptUpdate1Bit (
VoltAlgorithmObject *algObj,
VtRandomObject random,
unsigned char *dataToEncrypt,
unsigned int dataToEncryptLen,
unsigned char *encryptedData
)
{
int index;
unsigned int shiftCount;
unsigned char xorBit, nextBit, saveBit, mask;
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
while (dataToEncryptLen > 0)
{
/* For one byte of input, do 8 1-bit XOR's.
*/
mask = 0x80;
*encryptedData = *dataToEncrypt;
for (shiftCount = 0; shiftCount < 8; ++shiftCount)
{
/* Create a bit of XOR, it is the most significant bit of the XOR
* vector (after encrypting the currentVector).
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
xorBit = (cfbCtx->feedCtx.xorVector[0] & 0x80) >> shiftCount;
/* XOR the plaintext with the XOR bit.
*/
*encryptedData ^= xorBit;
/* Capture the resulting bit to update the vectors.
*/
xorBit = *encryptedData & mask;
/* Shift that bit to the low order position.
*/
nextBit = xorBit >> (7 - shiftCount);
/* Shift the currentVector left 1 bit.
*/
for (index = (int)(cfbCtx->feedCtx.blockSize) - 1; index >= 0; --index)
{
saveBit = cfbCtx->currentVector[index] >> 7;
cfbCtx->currentVector[index] <<= 1;
cfbCtx->currentVector[index] |= nextBit;
nextBit = saveBit;
}
mask >>= 1;
}
dataToEncryptLen--;
dataToEncrypt++;
encryptedData++;
}
return (0);
}
int CFBEncryptUpdate8Bit (
VoltAlgorithmObject *algObj,
VtRandomObject random,
unsigned char *dataToEncrypt,
unsigned int dataToEncryptLen,
unsigned char *encryptedData
)
{
unsigned int index;
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
while (dataToEncryptLen > 0)
{
/* Create a byte of XOR, it is the most significant byte of the XOR
* vector (after encrypting the currentVector).
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
/* XOR the plaintext with the XOR byte.
*/
*encryptedData = *dataToEncrypt ^ cfbCtx->feedCtx.xorVector[0];
/* Shift the currentVector left 1 byte.
*/
for (index = 0; index < cfbCtx->feedCtx.blockSize - 1; ++index)
cfbCtx->currentVector[index] = cfbCtx->currentVector[index + 1];
/* The new low order byte of the currentVector is the encrypted
* byte.
*/
cfbCtx->currentVector[cfbCtx->feedCtx.blockSize - 1] = *encryptedData;
dataToEncryptLen--;
dataToEncrypt++;
encryptedData++;
}
return (0);
}
int CFBDecryptUpdateBlock (
VoltAlgorithmObject *algObj,
VtRandomObject random,
unsigned char *dataToDecrypt,
unsigned int dataToDecryptLen,
unsigned char *decryptedData
)
{
unsigned int index, dataLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(algObj->voltObject.libraryCtx);
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
/* If we have some unused bits in the XOR vector, use them.
*/
if (cfbCtx->xorUsed < cfbCtx->feedCtx.blockSize)
{
/* Are there enough dataToDecrypt bytes to finish out the block of
* XOR bytes we have available?
*/
dataLen = cfbCtx->feedCtx.blockSize - cfbCtx->xorUsed;
if (dataToDecryptLen < dataLen)
dataLen = dataToDecryptLen;
for (index = cfbCtx->xorUsed; index < (cfbCtx->xorUsed + dataLen) ; ++index)
{
/* The ciphertext will be used to generate the next XOR vector,
* so save it.
*/
cfbCtx->currentVector[index] = *dataToDecrypt;
/* Decrypted data is the input XOR'd with a byte from the XOR
* vector.
*/
*decryptedData = *dataToDecrypt ^ cfbCtx->feedCtx.xorVector[index];
dataToDecrypt++;
decryptedData++;
}
dataToDecryptLen -= dataLen;
cfbCtx->xorUsed += dataLen;
}
/* So long as we have blocks, operate on them.
*/
while (dataToDecryptLen >= cfbCtx->feedCtx.blockSize)
{
/* Encrypt the currentVector to get the XOR vector.
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
/* The current ciphertext is the next block's data to encrypt.
*/
Z2Memcpy (
cfbCtx->currentVector, dataToDecrypt, cfbCtx->feedCtx.blockSize);
/* XOR each byte of input with the XOR vector. This will be the
* recovered text.
*/
for (index = 0; index < cfbCtx->feedCtx.blockSize; ++index)
decryptedData[index] =
cfbCtx->feedCtx.xorVector[index] ^ dataToDecrypt[index];
dataToDecrypt += cfbCtx->feedCtx.blockSize;
decryptedData += cfbCtx->feedCtx.blockSize;
dataToDecryptLen -= cfbCtx->feedCtx.blockSize;
}
/* After processing full blocks, if there's no more input, we're done.
*/
if (dataToDecryptLen == 0)
return (0);
/* We have some leftovers, create the XOR vector.
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
for (index = 0; index < dataToDecryptLen; ++index)
{
/* The ciphertext will be used to generate the next XOR vector,
* so save it.
*/
cfbCtx->currentVector[index] = dataToDecrypt[index];
decryptedData[index] =
dataToDecrypt[index] ^ cfbCtx->feedCtx.xorVector[index];
}
cfbCtx->xorUsed = dataToDecryptLen;
return (0);
}
int CFBDecryptUpdate1Bit (
VoltAlgorithmObject *algObj,
VtRandomObject random,
unsigned char *dataToDecrypt,
unsigned int dataToDecryptLen,
unsigned char *decryptedData
)
{
int index;
unsigned int shiftCount;
unsigned char xorBit, nextBit, saveBit, mask;
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
while (dataToDecryptLen > 0)
{
/* For one byte of input, do 8 1-bit XOR's.
*/
mask = 0x80;
*decryptedData = *dataToDecrypt;
for (shiftCount = 0; shiftCount < 8; ++shiftCount)
{
/* Save the current bit of ciphertext for the currentVector.
*/
nextBit = *decryptedData & mask;
nextBit >>= (7 - shiftCount);
/* Create a bit of XOR, it is the most significant bit of the XOR
* vector (after encrypting the currentVector).
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
xorBit = (cfbCtx->feedCtx.xorVector[0] & 0x80) >> shiftCount;
/* XOR the ciphertext with the XOR bit.
*/
*decryptedData ^= xorBit;
/* Shift the currentVector left 1 bit.
*/
for (index = (int)(cfbCtx->feedCtx.blockSize) - 1; index >= 0; --index)
{
saveBit = cfbCtx->currentVector[index] >> 7;
cfbCtx->currentVector[index] <<= 1;
cfbCtx->currentVector[index] |= nextBit;
nextBit = saveBit;
}
mask >>= 1;
}
dataToDecryptLen--;
dataToDecrypt++;
decryptedData++;
}
return (0);
}
int CFBDecryptUpdate8Bit (
VoltAlgorithmObject *algObj,
VtRandomObject random,
unsigned char *dataToDecrypt,
unsigned int dataToDecryptLen,
unsigned char *decryptedData
)
{
unsigned int index;
unsigned char saveByte;
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(algObj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
while (dataToDecryptLen > 0)
{
/* Save the current byte of ciphertext for the currentVector.
*/
saveByte = *dataToDecrypt;
/* Create a byte of XOR, it is the most significant byte of the XOR
* vector (after encrypting the currentVector).
*/
cfbCtx->AlgEncryptUpdate (
algObj, random, cfbCtx->currentVector, cfbCtx->feedCtx.blockSize,
cfbCtx->feedCtx.xorVector);
/* XOR the ciphertext with the XOR byte.
*/
*decryptedData = cfbCtx->feedCtx.xorVector[0] ^ *dataToDecrypt;
/* Shift the currentVector left 1 byte.
*/
for (index = 0; index < cfbCtx->feedCtx.blockSize - 1; ++index)
cfbCtx->currentVector[index] = cfbCtx->currentVector[index + 1];
/* The new low order byte of the currentVector is the encrypted
* byte.
*/
cfbCtx->currentVector[cfbCtx->feedCtx.blockSize - 1] = saveByte;
dataToDecryptLen--;
dataToDecrypt++;
decryptedData++;
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -