📄 fips186type.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 "random.h"
#include "fips186.h"
#include "mpint.h"
#include "errorctx.h"
/* This routine does the work. It allocates and fills in the contexts.
*
* @param obj The random object to set.
* @param info The info the caller passed in containing the parameters
* of usage.
* @param mpCtx The mpCtx to use. It may be the one in the info, it may
* be one from the libCtx.
* @param byteSize The size, in bytes, of the block.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV SetObjectFIPS186 VOLT_PROTO_LIST ((
VoltRandomObject *obj,
VtFips186PrngInfo *info,
VtMpIntCtx mpCtx,
unsigned int byteSize
));
/* This routine builds the digest algorithm object.
* <p>Note, after calling this routine there will be a created and set
* object, but it won't be initialized (DigestInit).
*
* @param libCtx The libCtx, it's needed to build a new object.
* @param fips186Ctx The context to find info necessary to build and
* where the created object will go.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV BuildDigestObject VOLT_PROTO_LIST ((
VtLibCtx libraryCtx,
VoltFips186PrngCtx *fips186Ctx
));
int VtRandomImplFips186Prng (
VtRandomObject *randObj,
Pointer info,
unsigned int flag
)
{
int status;
VoltRandomObject *obj = (VoltRandomObject *)(*randObj);
VtFips186PrngInfo *prngInfo = (VtFips186PrngInfo *)info;
VtMpIntCtx mpCtx = (VtMpIntCtx)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Check the flag, it should be VOLT_RAND_SET_TYPE_FLAG.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
if (flag != VOLT_RAND_SET_TYPE_FLAG)
break;
/* This InfoType has associated info.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (info == (Pointer)0)
break;
/* There must be XKEY and it must be within the acceptable size
* range.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ( (prngInfo->XKEY.data == (unsigned char *)0) ||
(prngInfo->XKEY.len < FIPS_186_PRNG_MIN_XKEY_SIZE) ||
(prngInfo->XKEY.len > FIPS_186_PRNG_MAX_XKEY_SIZE) )
break;
/* The prime, if passed in, must be exactly 160 bits long. And
* there must be an mpCtx.
*/
if ( (prngInfo->primeQ.data != (unsigned char *)0) &&
(prngInfo->primeQ.len != 0) )
{
VOLT_SET_FNCT_LINE (fnctLine)
if (prngInfo->primeQ.len != 20)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if ((prngInfo->primeQ.data[0] & 0x80) == 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NO_MATH_LIBRARY;
mpCtx = prngInfo->mpCtx;
if (mpCtx == (VtMpIntCtx)0)
{
mpCtx = (VtMpIntCtx)VoltGetLibCtxInfo (
obj->voltObject.libraryCtx, VOLT_LIB_CTX_INFO_TYPE_MP_CTX);
if (mpCtx == (VtMpIntCtx)0)
break;
}
/* We must have a valid MpIntCtx.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_MP_INT_CTX;
if (VOLT_OBJECT_TYPE_NOT_EQUAL (mpCtx, VOLT_OBJECT_TYPE_MP_INT_CTX))
break;
}
/* Make sure the variation is valid.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ( (prngInfo->variation != FIPS_186_PRNG_3_1_ALG) &&
(prngInfo->variation != FIPS_186_PRNG_3_1_CERTIFY) &&
(prngInfo->variation != FIPS_186_PRNG_3_2_ALG) &&
(prngInfo->variation != FIPS_186_PRNG_3_2_CERTIFY) )
break;
/* Check the object, it should not yet be set.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_SET;
if (obj->GenerateRandomBytes != (VGenerateRandomBytes)0)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = SetObjectFIPS186 (obj, prngInfo, mpCtx, 32);
} while (0);
/* If successful, set the FIPS bit in the object type, this object
* is a FIPS object.
*/
if (status == 0)
obj->voltObject.objectType |= VOLT_OBJECT_TYPE_FIPS;
VOLT_LOG_ERROR_COMPARE (
status, obj->voltObject.libraryCtx, status, errorType, fnctLine,
"VtRandomImplFips186Prng", (char *)0)
return (status);
}
static int SetObjectFIPS186 (
VoltRandomObject *obj,
VtFips186PrngInfo *info,
VtMpIntCtx mpCtx,
unsigned int byteSize
)
{
int status;
unsigned int bufferSize, offset;
unsigned char *buffer = (unsigned char *)0;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltFips186PrngCtx *fips186Ctx;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Allocate enough space for a Fips186Ctx and buffers for xseed,
* xkey and partial seed collection. The buffers after the struct
* are byte arrays so we don't need to worry about alignment.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
bufferSize = sizeof (VoltFips186PrngCtx) + (3 * byteSize);
buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
Z2Memset (buffer, 0, bufferSize);
/* Locate the buffers.
*/
fips186Ctx = (VoltFips186PrngCtx *)buffer;
offset = sizeof (VoltFips186PrngCtx);
/* Populate the context.
*/
/* Clone the MpIntCtx if there is one.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
if (mpCtx != (VoltMpIntCtx *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCloneObject ((Pointer)mpCtx, (Pointer *)&(fips186Ctx->mpCtx));
if (status != 0)
break;
}
fips186Ctx->variation = info->variation;
fips186Ctx->blockSizeBits = byteSize * 8;
fips186Ctx->byteSize = byteSize;
fips186Ctx->previousBytesFlag = VOLT_FIPS_186_INIT;
fips186Ctx->xseed = buffer + offset;
offset += byteSize;
fips186Ctx->xkey = buffer + offset;
offset += byteSize;
fips186Ctx->seedBuffer = buffer + offset;
/* Copy XKEY with prepended 0's (if the length is not as long as
* the byteSize).
*/
offset = byteSize - info->XKEY.len;
Z2Memcpy (fips186Ctx->xkey + offset, info->XKEY.data, info->XKEY.len);
/* We'll need a digest object.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = BuildDigestObject ((VtLibCtx)libCtx, fips186Ctx);
if (status != 0)
break;
/* If there's a primeQ, get it into the context as an MpInt.
*/
if ( (info->primeQ.data != (unsigned char *)0) &&
(info->primeQ.len != 0) )
{
VOLT_SET_FNCT_LINE (fnctLine)
status = fips186Ctx->mpCtx->CreateMpInt (
(Pointer)(fips186Ctx->mpCtx), &(fips186Ctx->primeQ));
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = fips186Ctx->mpCtx->OctetStringToMpInt (
0, info->primeQ.data, info->primeQ.len, fips186Ctx->primeQ);
if (status != 0)
break;
/* We'll need base and reduction MpInt's as well.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = fips186Ctx->mpCtx->CreateMpInt (
(Pointer)(fips186Ctx->mpCtx), &(fips186Ctx->base));
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = fips186Ctx->mpCtx->CreateMpInt (
(Pointer)(fips186Ctx->mpCtx), &(fips186Ctx->reduction));
if (status != 0)
break;
}
obj->SeedRandom = FIPS186SeedRandom;
obj->GenerateRandomBytes = FIPS186GenerateRandomBytes;
obj->localRandomCtx = (Pointer)fips186Ctx;
obj->LocalRandomCtxDestroy = FIPS186CtxDestroy;
status = 0;
} while (0);
/* If everything worked, return 0.
*/
if (status == 0)
return (0);
/* If something went wrong, destroy anything we created.
*/
FIPS186CtxDestroy ((Pointer)obj, (Pointer)buffer);
VOLT_LOG_ERROR (
obj->voltObject.libraryCtx, status, errorType, fnctLine,
"SetObjectFIPS186", (char *)0)
return (status);
}
void FIPS186CtxDestroy (
Pointer object,
Pointer ctx
)
{
VoltRandomObject *obj = (VoltRandomObject *)object;
VoltLibCtx *libCtx;
VoltFips186PrngCtx *fips186Ctx = (VoltFips186PrngCtx *)ctx;
/* Anything to destroy?
*/
if (ctx == (Pointer)0)
return;
libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
/* First, destroy the digest object.
*/
if (fips186Ctx->digestObj != (VtAlgorithmObject)0)
VtDestroyAlgorithmObject (&(fips186Ctx->digestObj));
/* If there are primeQ, base, reduction, destroy them.
*/
if (fips186Ctx->primeQ != (VoltMpInt *)0)
fips186Ctx->mpCtx->DestroyMpInt (&(fips186Ctx->primeQ));
if (fips186Ctx->base != (VoltMpInt *)0)
fips186Ctx->mpCtx->DestroyMpInt (&(fips186Ctx->base));
if (fips186Ctx->reduction != (VoltMpInt *)0)
fips186Ctx->mpCtx->DestroyMpInt (&(fips186Ctx->reduction));
if (fips186Ctx->mpCtx != (VoltMpIntCtx *)0)
VtDestroyMpIntCtx ((VtMpIntCtx *)&(fips186Ctx->mpCtx));
/* Now, free the memory.
*/
Z2Free (ctx);
}
static int BuildDigestObject (
VtLibCtx libraryCtx,
VoltFips186PrngCtx *fips186Ctx
)
{
int status;
unsigned char sha1State[24] =
{
0x67, 0x45, 0x23, 0x01,
0xEF, 0xCD, 0xAB, 0x89,
0x98, 0xBA, 0xDC, 0xFE,
0x10, 0x32, 0x54, 0x76,
0xC3, 0xD2, 0xE1, 0xF0,
0x67, 0x45, 0x23, 0x01,
};
VtGeneralSHA1Info shaInfo;
VOLT_DECLARE_FNCT_LINE (fnctLine)
shaInfo.padding = VT_SHA1_FIPS_186_PAD;
/* What's the starting point? Regular SHA-1 or a shifted SHA-1 state?
*/
shaInfo.initState.data = sha1State;
shaInfo.initState.len = 20;
if ( (fips186Ctx->variation == FIPS_186_PRNG_3_2_ALG) ||
(fips186Ctx->variation == FIPS_186_PRNG_3_2_CERTIFY) )
shaInfo.initState.data = sha1State + 4;
/* Create the SHA-1 object with the appropriate starting point.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
libraryCtx, VtAlgorithmImplGeneralSHA1, (Pointer)&shaInfo,
&(fips186Ctx->digestObj));
VOLT_LOG_ERROR_COMPARE (
status, libraryCtx, status, 0, fnctLine, "BuildDigestObject", (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -