📄 blockalgid.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "cipher.h"
#include "block.h"
#include "cfb.h"
#include "oidlist.h"
#include "algid.h"
#include "errorctx.h"
/* Set up the OpenSSL ASN.1 template For CFB Params
*/
ASN1_SEQUENCE (Asn1CFBParams) =
{
ASN1_SIMPLE (Asn1CFBParams, iv, ASN1_OCTET_STRING),
ASN1_SIMPLE (Asn1CFBParams, transfer, ASN1_INTEGER)
} ASN1_SEQUENCE_END (Asn1CFBParams);
IMPLEMENT_ASN1_FUNCTIONS (Asn1CFBParams)
/* Build the parameters of a block cipher.
* ECB: nothing.
* CBC: iv OCTET STRING
* OFB: iv OCTET STRING
* CFB: SEQ { iv OCTET STRING, bits INTEGER }
* <p>This function allocates space, the caller must free it.
* <p>Note that this function is valid only for block cipher algorithms
* that have no parameters other than the feedback params.
*
* @param obj Contains the info to encode.
* @param params Where the routine will go to deposit the pointer to
* the allocated space.
* @param paramsLen Where the routine will go to deposit the length of
* the encoded params.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV BuildParamsAlloc VOLT_PROTO_LIST ((
VoltAlgorithmObject *obj,
unsigned char **params,
unsigned int *paramsLen
));
/* Decode the CFB params.
* <p>This function creates an Asn1CFBParams "object". It is the
* responsibility of the caller to destroy it.
* <p>Upon return, the IV will be at cfbParams->iv->data.
*
* @param libCtx The libCtx to use.
* @param params The encoded params.
* @param paramsLen The length, in bytes, of the encoded params.
* @param cfbParams The address where the function will deposit the
* created object.
* @param transferSizeBits The address where the function will deposit
* the transfer size from the params.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV DecodeCFBParamsCreate VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
unsigned char *params,
unsigned int paramsLen,
Asn1CFBParams **cfbParams,
unsigned int *transferSizeBits
));
int VoltDerCoderBlockCipher (
unsigned int flag,
Pointer object,
VtDerCoderInfo *coderInfo,
VoltBlockCipherAlgIdData *algIdData
)
{
int status;
unsigned int bufferSize, paramsLen, feedback;
VoltLibCtx *libCtx;
VtAlgorithmObject *theObject;
VoltAlgorithmObject *obj = (VoltAlgorithmObject *)0;
VoltDerCoderEncodeData *encodeData = &(coderInfo->info.encodeData);
VoltDerCoderGetAlgData *getAlgData = &(coderInfo->info.getAlgData);
VoltDerCoderDecodeData *decodeData = &(coderInfo->info.decodeData);
unsigned char *params = (unsigned char *)0;
Asn1AlgorithmId *algId;
Asn1CFBParams *cfbParams = (Asn1CFBParams *)0;
VtBlockCipherInfo blockCipherInfo;
VtItem ivItem;
VtCFBInfo cfbInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
switch (flag)
{
default:
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
break;
case VOLT_DER_TYPE_ENCODE_FLAG:
/* If the flag is ENCODE, return the algID.
*/
/* Check the args.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NON_NULL_ARG;
if (object != (Pointer)0)
break;
/* The info should be an object.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (encodeData->info == (Pointer)0)
break;
/* We need a place to drop the length.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (encodeData->encodingLen == (unsigned int *)0)
break;
bufferSize = encodeData->bufferSize;
if (encodeData->encoding == (unsigned char *)0)
bufferSize = 0;
/* Make sure the object is valid.
*/
VOLT_SET_FNCT_LINE (fnctLine)
obj = (VoltAlgorithmObject *)(encodeData->info);
status = VT_ERROR_INVALID_ALG_OBJ;
if (VOLT_OBJECT_TYPE_NOT_EQUAL (obj, VOLT_OBJECT_TYPE_ALGORITHM))
break;
/* Make sure this object is the expected alg/feed/pad.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
if ( (obj->algClass != VOLT_CLASS_BLOCK_CIPHER) ||
(obj->subAlg1 != algIdData->subAlg1) ||
(obj->subAlg2 != algIdData->subAlg2) )
break;
libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
/* Build the params encoding.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = BuildParamsAlloc (obj, ¶ms, ¶msLen);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltEncodeAlgId (
libCtx, algIdData->oid, algIdData->oidLen, params, paramsLen, 5,
encodeData->encoding, bufferSize, encodeData->encodingLen);
break;
case VOLT_DER_TYPE_DECODE_FLAG:
/* If the flag is decode, set the object to perform the specified
* block operation.
*/
/* Check the args.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NULL_ARG;
if (object == (Pointer)0)
break;
theObject = (VtAlgorithmObject *)object;
VOLT_SET_FNCT_LINE (fnctLine)
if (*theObject == (VtAlgorithmObject)0)
break;
obj = (VoltAlgorithmObject *)(*theObject);
/* Make sure we're calling for an algorithm and not param or key.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
if (decodeData->type != VOLT_DER_TYPE_ALG_ID_FLAG)
break;
/* Make sure this is the correct algId.
*/
VOLT_SET_FNCT_LINE (fnctLine)
algId = (Asn1AlgorithmId *)(decodeData->asn1Object);
if (algId->oid->base.length != (int)(algIdData->oidLen))
break;
libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VOLT_SET_FNCT_LINE (fnctLine)
if (Z2Memcmp (
algId->oid->base.data, algIdData->oid, algIdData->oidLen) != 0)
break;
/* Set the object with block cipher info.
*/
Z2Memset (&blockCipherInfo, 0, sizeof (blockCipherInfo));
feedback = algIdData->subAlg2 & VOLT_SUB_ALG_FEED_MASK;
if ( (feedback == VOLT_SUB_ALG_CBC) || (feedback == VOLT_SUB_ALG_OFB) )
{
ivItem.data = algId->params->base.data + 2;
ivItem.len = (unsigned int)(algId->params->base.length - 2);
if (feedback == VOLT_SUB_ALG_CBC)
blockCipherInfo.feedback = VtFeedbackCBC;
else
blockCipherInfo.feedback = VtFeedbackOFB;
blockCipherInfo.feedbackInfo = (Pointer)&ivItem;
}
else if (feedback == VOLT_SUB_ALG_CFB)
{
blockCipherInfo.feedback = VtFeedbackCFB;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = DecodeCFBParamsCreate (
libCtx, algId->params->base.data,
(unsigned int)(algId->params->base.length),
&cfbParams, &cfbInfo.transferSizeBits);
if (status != 0)
break;
cfbInfo.initVector.data = cfbParams->iv->data;
cfbInfo.initVector.len = (unsigned int)(cfbParams->iv->length);
blockCipherInfo.feedbackInfo = (Pointer)&cfbInfo;
}
if ((algIdData->subAlg2 & VOLT_SUB_ALG_P5_PAD) != 0)
blockCipherInfo.padding = VtPaddingPkcs5;
VtDestroyAlgorithmObject (theObject);
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
libCtx, algIdData->algImpl, (Pointer)&blockCipherInfo,
theObject);
break;
case VOLT_DER_TYPE_GET_ALG_FLAG:
/* If the flag is get alg, check the input to see if it's the
* same oid.
*/
/* Check the args.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NON_NULL_ARG;
if (object != (Pointer)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if ( (getAlgData->algorithm == (unsigned int *)0) ||
(getAlgData->oid == (unsigned char *)0) )
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
if (getAlgData->oidLen != algIdData->oidLen)
break;
libCtx = getAlgData->libCtx;
VOLT_SET_FNCT_LINE (fnctLine)
if (Z2Memcmp (getAlgData->oid, algIdData->oid, algIdData->oidLen) != 0)
break;
/* The OID matches, the algorithm is the block cipher indicated.
*/
*(getAlgData->algorithm) = algIdData->algorithm;
getAlgData->SymKeyParam = algIdData->KeyParam;
getAlgData->DigestImpl = (VtAlgorithmImpl *)0;
status = 0;
}
if (params != (unsigned char *)0)
Z2Free (params);
if (cfbParams != (Asn1CFBParams *)0)
Asn1CFBParams_free (cfbParams);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, object, status, 0, errorType,
(char *)0, "VoltDerCoderBlockCipher", fnctLine, (char *)0)
return (status);
}
static int BuildParamsAlloc (
VoltAlgorithmObject *obj,
unsigned char **params,
unsigned int *paramsLen
)
{
int status, encodingLen;
unsigned int feedback;
unsigned char *buffer = (unsigned char *)0;
unsigned char *temp;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltCipherClassCtx *cipherCtx = (VoltCipherClassCtx *)(obj->classCtx);
VoltBlockCipherCtx *blockCtx =
(VoltBlockCipherCtx *)(cipherCtx->localCipherCtx);
VoltFeedbackCtx *feedCtx = (VoltFeedbackCtx *)(blockCtx->feedbackCtx);
VoltCFBCtx *cfbCtx = (VoltCFBCtx *)(blockCtx->feedbackCtx);
Asn1CFBParams *cfbParams = (Asn1CFBParams *)0;
VOLT_DECLARE_FNCT_LINE (fnctLine)
feedback = (unsigned int)(obj->subAlg2 & VOLT_SUB_ALG_FEED_MASK);
*params = (unsigned char *)0;
*paramsLen = 0;
/* If the feedback is ECB, params is NULL and paramsLen is 0.
*/
if (feedback == VOLT_SUB_ALG_ECB)
return (0);
/* If the feedback is CBC or OFB, the params consist of an OCTET
* STRING, the IV.
*/
if ( (feedback == VOLT_SUB_ALG_CBC) || (feedback == VOLT_SUB_ALG_OFB) )
{
/* Assume we'll never have an IV longer than 127 bytes.
*/
VOLT_SET_FNCT_LINE (fnctLine)
buffer = (unsigned char *)Z2Malloc (feedCtx->blockSize + 2, 0);
if (buffer == (unsigned char *)0)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, VT_ERROR_MEMORY, VT_ERROR_TYPE_PRIMARY,
fnctLine, "BuildParamsAlloc", (char *)0)
return (VT_ERROR_MEMORY);
}
buffer[0] = 4;
buffer[1] = feedCtx->blockSize;
Z2Memcpy (buffer + 2, feedCtx->initVector, feedCtx->blockSize);
*params = buffer;
*paramsLen = feedCtx->blockSize + 2;
return (0);
}
/* The feedback is not ECB, CBC or OFB, it had better be CFB.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (feedback != VOLT_SUB_ALG_CFB)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, VT_ERROR_INVALID_INPUT, VT_ERROR_TYPE_PRIMARY,
fnctLine, "BuildParamsAlloc", (char *)0)
return (VT_ERROR_INVALID_INPUT);
}
do
{
/* Create the object.
*/
status = VT_ERROR_MEMORY;
VOLT_SET_FNCT_LINE (fnctLine)
cfbParams = Asn1CFBParams_new ();
if (cfbParams == (Asn1CFBParams *)0)
break;
/* Set the fields.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_STRING_set (
cfbParams->iv, feedCtx->initVector, feedCtx->blockSize) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_INTEGER_set (
cfbParams->transfer, (long)(cfbCtx->transferSizeBits)) != 1)
break;
/* Call encode with NULL to get the size.
*/
status = VT_ERROR_INVALID_INPUT;
VOLT_SET_FNCT_LINE (fnctLine)
encodingLen = i2d_Asn1CFBParams (cfbParams, (unsigned char **)0);
if (encodingLen == 0)
break;
status = VT_ERROR_MEMORY;
VOLT_SET_FNCT_LINE (fnctLine)
buffer = (unsigned char *)Z2Malloc (encodingLen, 0);
if (buffer == (unsigned char *)0)
break;
/* Call with a buffer, the call will fill it.
*/
status = VT_ERROR_INVALID_INPUT;
temp = buffer;
VOLT_SET_FNCT_LINE (fnctLine)
encodingLen = i2d_Asn1CFBParams (cfbParams, &temp);
if (encodingLen == 0)
break;
*params = buffer;
*paramsLen = (unsigned int)encodingLen;
status = 0;
} while (0);
if (cfbParams != (Asn1CFBParams *)0)
Asn1CFBParams_free (cfbParams);
VOLT_LOG_ERROR_COMPARE (
status, (VtLibCtx)libCtx, status, VT_ERROR_TYPE_PRIMARY,
fnctLine, "BuildParamsAlloc", (char *)0)
return (status);
}
static int DecodeCFBParamsCreate (
VoltLibCtx *libCtx,
unsigned char *params,
unsigned int paramsLen,
Asn1CFBParams **cfbParams,
unsigned int *transferSizeBits
)
{
int status, index;
unsigned int transferSize;
Asn1CFBParams *decodeParams = (Asn1CFBParams *)0;
unsigned char *temp;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Create the object.
*/
status = VT_ERROR_MEMORY;
VOLT_SET_FNCT_LINE (fnctLine)
decodeParams = Asn1CFBParams_new ();
if (decodeParams == (Asn1CFBParams *)0)
break;
/* Decode.
*/
status = VT_ERROR_UNKNOWN_BER;
temp = params;
VOLT_SET_FNCT_LINE (fnctLine)
d2i_Asn1CFBParams (&decodeParams, &temp, paramsLen);
/* Did it work?
*/
if (decodeParams == (Asn1CFBParams *)0)
break;
/* If successful, return the object and the transfer size.
*/
*cfbParams = decodeParams;
transferSize = 0;
for (index = 0; index < decodeParams->transfer->length; ++index)
{
transferSize <<= 8;
transferSize |= (unsigned int)(decodeParams->transfer->data[index]);
}
*transferSizeBits = transferSize;
status = 0;
} while (0);
if (status == 0)
return (0);
if (decodeParams != (Asn1CFBParams *)0)
Asn1CFBParams_free (decodeParams);
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, VT_ERROR_TYPE_PRIMARY,
fnctLine, "DecodeCFBParamsCreate", (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -