📄 hmactype.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "digest.h"
#include "voltmac.h"
#include "hmac.h"
#include "errorctx.h"
int VtAlgorithmImplHMAC (
VtAlgorithmObject *object,
Pointer info,
unsigned int flag
)
{
int status;
unsigned int offset, bufferSize;
VtHMACInfo *hmacInfo;
VoltAlgorithmObject *obj = (VoltAlgorithmObject *)(*object);
unsigned char *buffer = (unsigned char *)0;
VoltLibCtx *libCtx = (VoltLibCtx *)obj->voltObject.libraryCtx;
VoltMACClassCtx *macCtx = (VoltMACClassCtx *)0;
VoltHMACCtx *hmacCtx = (VoltHMACCtx *)0;
VoltAlgorithmObject *digestObj = (VoltAlgorithmObject *)0;
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
#if VOLT_ALIGNMENT != 1
unsigned int pad;
#endif
do
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
if (flag != VOLT_ALG_SET_TYPE_FLAG)
break;
/* Get the info, make sure it's what we expect.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (info == (Pointer)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
hmacInfo = (VtHMACInfo *)info;
if (hmacInfo->digestImpl == (VtAlgorithmImpl *)0)
break;
/* Build a digest object from the Impl
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, hmacInfo->digestImpl, hmacInfo->digestImplInfo,
(VtAlgorithmObject *)&digestObj);
if (status != 0)
break;
/* We blindly used the digestImpl in the hmacInfo. Was it really a
* digest object?
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (digestObj->algClass != VOLT_CLASS_DIGEST)
break;
digestCtx = (VoltDigestClassCtx *)(digestObj->classCtx);
bufferSize = sizeof (VoltMACClassCtx) + sizeof (VoltHMACCtx);
#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 (VoltMACClassCtx), pad)
bufferSize += pad;
#endif
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
Z2Memset (buffer, 0, bufferSize);
/* Locate the contexts.
*/
macCtx = (VoltMACClassCtx *)buffer;
offset = sizeof (VoltMACClassCtx);
#if VOLT_ALIGNMENT != 1
offset += pad;
#endif
hmacCtx = (VoltHMACCtx *)(buffer + offset);
/* Allocate memory for other fields. The maximum Key length is
* equal to the block length of underlying digest function. If we
* use the same HMAC object with different secrets it's more
* efficient to allocate memory to hold the maximun length secret
* rather than deallocating and allocating memory again and again.
* This way even though we allocate some extra bytes of memory when
* secret length is less than the block length (something not
* recommended) of the underlying message digest, our code is lot
* faster.
*/
VOLT_SET_FNCT_LINE (fnctLine)
hmacCtx->key = (unsigned char *) Z2Malloc (
digestCtx->blockLen, VOLT_MEMORY_SENSITIVE);
if (hmacCtx->key == (unsigned char *)0 )
break;
VOLT_SET_FNCT_LINE (fnctLine)
hmacCtx->ipad = (unsigned char *) Z2Malloc (digestCtx->blockLen, 0);
if (hmacCtx->ipad == (unsigned char *)0 )
break;
VOLT_SET_FNCT_LINE (fnctLine)
hmacCtx->opad = (unsigned char *) Z2Malloc (digestCtx->blockLen, 0);
if (hmacCtx->opad == (unsigned char *)0 )
break;
VOLT_SET_FNCT_LINE (fnctLine)
hmacCtx->ipadHash = (unsigned char *) Z2Malloc (digestCtx->digestSize, 0);
if (hmacCtx->ipadHash == (unsigned char *)0 )
break;
Z2Memset (hmacCtx->key, 0 , digestCtx->blockLen);
hmacCtx->digestObj = digestObj;
/* Populate the MAC ctx
*/
macCtx->MACInit = HMACInit;
macCtx->MACUpdate = HMACUpdate;
macCtx->MACFinal = HMACFinal;
macCtx->localMacCtx = (Pointer)hmacCtx;
macCtx->LocalMACCtxDestroy = VoltLocalHMACCtxDestroy;
/* ClassCtxDestroy will destroy the local ctx data
*/
obj->algClass = VOLT_CLASS_MAC;
obj->classCtx = (Pointer)macCtx;
obj->ClassCtxDestroy = VoltMACClassCtxDestroy;
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.
*/
obj->state = VOLT_STATE_ERROR;
if (hmacCtx != (VoltHMACCtx *)0 )
{
if (hmacCtx->key != (unsigned char *)0 )
Z2Free (hmacCtx->key);
if (hmacCtx->ipad != (unsigned char *) 0)
Z2Free (hmacCtx->ipad);
if (hmacCtx->opad != (unsigned char *) 0)
Z2Free (hmacCtx->opad);
if (hmacCtx->ipadHash != (unsigned char *)0 )
Z2Free (hmacCtx->ipadHash);
}
VtDestroyAlgorithmObject ((VtAlgorithmObject *)&digestObj);
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, errorType, fnctLine,
"VtAlgorithmImplHMAC", (char *)0)
return (status);
}
void VoltLocalHMACCtxDestroy (
Pointer obj,
Pointer ctx
)
{
VoltAlgorithmObject *algObj;
VoltLibCtx *libCtx;
VoltHMACCtx *hmacCtx;
/* Anything to destroy?
*/
if ( (obj == (Pointer)0) || (ctx == (Pointer)0) )
return;
algObj = (VoltAlgorithmObject *)obj;
libCtx = (VoltLibCtx *)algObj->voltObject.libraryCtx;
hmacCtx = (VoltHMACCtx *)ctx;
/* Destroy the underlying digest object
*/
VtDestroyAlgorithmObject ((VtAlgorithmObject *)&(hmacCtx->digestObj));
/* free all the memory that was allocated while creating the object.
*/
if (hmacCtx->key != (unsigned char *)0 )
Z2Free (hmacCtx->key);
if (hmacCtx->ipad != (unsigned char *) 0)
Z2Free (hmacCtx->ipad);
if (hmacCtx->opad != (unsigned char *) 0)
Z2Free (hmacCtx->opad);
if (hmacCtx->ipadHash != (unsigned char *)0 )
Z2Free (hmacCtx->ipadHash);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -