📄 blocktype.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 "errorctx.h"
int VoltAlgorithmSetBlockCipher (
VoltAlgorithmObject *object,
VoltBlockAlgSetter Cipher,
VtBlockCipherInfo *blockInfo
)
{
int status, tStatus;
#if VOLT_ALIGNMENT != 1
unsigned int pad;
#endif
unsigned int bufferSize, unprocessedBufferSize, offset;
unsigned char *buffer = (unsigned char *)0;
VoltAlgorithmObject *obj = (VoltAlgorithmObject *)object;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltCipherClassCtx *cipherCtx;
VoltBlockCipherCtx *blockCtx;
VoltFeedbackInfo feedInfo;
VoltPaddingInfo padInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Allocate enough space for a CipherCtx and a BlockCtx.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
bufferSize = sizeof (VoltCipherClassCtx) + sizeof (VoltBlockCipherCtx);
#if VOLT_ALIGNMENT != 1
/* If the alignment is 1, there's no need to pad. If not, compute
* the pad length.
*/
VOLT_COMPUTE_ALIGN_PAD (VOLT_ALIGNMENT, sizeof (VoltCipherClassCtx), pad)
bufferSize += pad;
#endif
buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
Z2Memset (buffer, 0, bufferSize);
/* Locate the contexts.
*/
cipherCtx = (VoltCipherClassCtx *)buffer;
offset = sizeof (VoltCipherClassCtx);
#if VOLT_ALIGNMENT != 1
offset += pad;
#endif
blockCtx = (VoltBlockCipherCtx *)(buffer + offset);
/* Populate the object and contexts.
*/
obj->algClass = VOLT_CLASS_BLOCK_CIPHER;
obj->classCtx = (Pointer)cipherCtx;
obj->ClassCtxDestroy = BlockCipherClassCtxDestroy;
cipherCtx->localCipherCtx = (Pointer)blockCtx;
/* Set the setState to indicate we've set up for a block cipher,
* but have not yet filled in the algorithmic details.
*/
cipherCtx->setState = VOLT_BLOCK_SET_STATE_BLOCK;
/* To fill the rest of the fields, call the Setters for Cipher,
* Feedback and Padding.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = Cipher (obj, blockInfo->cipherInfo, VOLT_BLOCK_ALG_SET_TYPE_FLAG);
if (status != 0)
break;
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (blockInfo->feedback != (VtFeedbackMode *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
feedInfo.info = blockInfo->feedbackInfo;
tStatus = blockInfo->feedback (
(VtAlgorithmObject)object, (VtFeedbackInfo *)&feedInfo,
VOLT_FEEDBACK_SET_TYPE_FLAG);
if (tStatus != 0)
break;
}
else
{
obj->subAlg2 = VOLT_SUB_ALG_ECB;
cipherCtx->setState = VOLT_BLOCK_SET_STATE_FEED;
}
if (blockInfo->padding != (VtPaddingScheme *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
padInfo.info = blockInfo->paddingInfo;
tStatus = blockInfo->padding (
(VtAlgorithmObject)object, (VtPaddingInfo *)&padInfo,
VOLT_PADDING_SET_TYPE_FLAG);
if (tStatus != 0)
break;
}
else
{
obj->subAlg2 |= VOLT_SUB_ALG_NO_PAD;
}
/* If, after loading the cipher, feedback and padding scheme, the
* blockSize is still not 1, we'll need an unprocessedData buffer.
*/
if ( (cipherCtx->plainBlockSize != 1) || (cipherCtx->cipherBlockSize != 1) )
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
unprocessedBufferSize = cipherCtx->plainBlockSize;
if (cipherCtx->plainBlockSize < cipherCtx->cipherBlockSize)
unprocessedBufferSize = cipherCtx->cipherBlockSize;
cipherCtx->unprocessedData = (unsigned char *)Z2Malloc (
unprocessedBufferSize, VOLT_MEMORY_SENSITIVE);
if (cipherCtx->unprocessedData == (unsigned char *)0)
break;
}
if (cipherCtx->GetOutputSize == (VGetOutputSize)0)
cipherCtx->GetOutputSize = VoltDefaultEncDecGetOutputSize;
/* It set successfully, indicate that.
*/
cipherCtx->setState = VOLT_CIPHER_SET_STATE_COMPLETE;
status = 0;
} while (0);
/* If everything worked, return 0.
*/
if (status == 0)
return (0);
/* If something went wrong, destroy anything we created and indicate
* that this object is not usable.
*/
BlockCipherClassCtxDestroy ((Pointer)obj, (Pointer)cipherCtx);
obj->algClass = 0;
obj->classCtx = (Pointer)0;
obj->ClassCtxDestroy = (VCtxDestroy)0;
obj->state = VOLT_STATE_ERROR;
VOLT_LOG_ERROR (
obj->voltObject.libraryCtx, status, errorType, fnctLine,
"VoltAlgorithmSetBlockCipher", (char *)0)
return (status);
}
void BlockCipherClassCtxDestroy (
Pointer algObj,
Pointer ctx
)
{
VoltAlgorithmObject *obj;
VoltLibCtx *libCtx;
VoltCipherClassCtx *cipherCtx;
VoltBlockCipherCtx *blockCtx;
/* Is there anything to destroy?
*/
if ( (algObj == (Pointer)0) || (ctx == (Pointer)0) )
return;
obj = (VoltAlgorithmObject *)algObj;
libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
cipherCtx = (VoltCipherClassCtx *)ctx;
/* First, destroy block context.
Destroy the individual contexts, then overwrite the memory. The
memory for the blockCtx was allocated along with the cipherCtx, so
don't free it. It will be freed when the cipherCtx is freed.
*/
blockCtx = (VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
if (blockCtx->AlgCtxDestroy != (VCtxDestroy)0)
blockCtx->AlgCtxDestroy (algObj, blockCtx->algCtx);
if (blockCtx->FeedbackCtxDestroy != (VCtxDestroy)0)
blockCtx->FeedbackCtxDestroy (algObj, blockCtx->feedbackCtx);
/* Destroy the Padding context, if there is one.
*/
if (cipherCtx->PadCtxDestroy != (VCtxDestroy)0)
cipherCtx->PadCtxDestroy (algObj, cipherCtx->padCtx);
/* Free the unprocessedData buffer, if there is one.
*/
if (cipherCtx->unprocessedData != (unsigned char *)0)
Z2Free (cipherCtx->unprocessedData);
/* Overwrite the memory of the cipher context and free the memory.
*/
Z2Free (cipherCtx);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -