📄 fips186impl.c
字号:
return (status);
}
static int TestSeed (
VoltLibCtx *libCtx,
VoltFips186PrngCtx *fips186Ctx
)
{
int status, compareResult;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* The FIPS seed test just wants to make sure XKEY and XSEED are not
* the same. The data in the seedBuffer is going to become XSEED.
*/
compareResult = Z2Memcmp (
fips186Ctx->xkey, fips186Ctx->seedBuffer, fips186Ctx->byteSize);
if (compareResult != 0)
return (0);
/* If we're building this for the FIPS shared library, we want to set
* the FIPS error.
*/
#if VOLT_BUILD == VOLT_BUILD_FIPS_SHARED
VOLT_SET_FNCT_LINE (fnctLine)
VoltSetFipsError (VT_ERROR_FIPS_DRNG_SEED);
status = VT_ERROR_FIPS_DRNG_SEED;
#else
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INSUFFICIENT_SEED;
#endif /* VOLT_BUILD == VOLT_BUILD_FIPS_SHARED */
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, VT_ERROR_TYPE_PRIMARY, fnctLine,
"TestSeed", (char *)0)
return (status);
}
static int TestOutput (
VoltLibCtx *libCtx,
VoltFips186PrngCtx *fips186Ctx
)
{
int status, compareResult;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Initialize compareResult to 1 (not equal, meaning the two blocks
* are not equal). If we do no compare, that's correct. If we do a
* compare and the blocks are the same, this value will change.
*/
compareResult = 1;
/* When copying, copy the full contents, when comparing, compare
* the number of bytes we will output. If we copy more than
* necessary, it won't affect the compare.
*/
switch (fips186Ctx->previousBytesFlag)
{
case VOLT_FIPS_186_INIT:
/* If previousBytesFlag is VOLT_FIPS_186_INIT, we have not yet
* placed any data into the previousBytes buffer, there's nothing
* to check. Copy the currentBytes into the previousBytes buffer.
* Set currentBytesLen to 0 so the generate function will not
* output anything.
* If variation is CERTIFY, set previousBytesFlag to
* VOLT_FIPS_186_CURRENT_BUFFER. From now on, work normally.
* If variation is ALG (not CERTIFY), set previousBytesFlag to
* VOLT_FIPS_186_NO_BUFFER.
*/
Z2Memcpy (
fips186Ctx->previousBytes, fips186Ctx->currentBytes,
2 * FIPS_186_PRNG_OUTPUT_BLOCK_SIZE);
fips186Ctx->currentBytesLen = 0;
fips186Ctx->previousBytesFlag = VOLT_FIPS_186_NO_BUFFER;
if ((fips186Ctx->variation & FIPS_186_CERTIFY) != 0)
fips186Ctx->previousBytesFlag = VOLT_FIPS_186_CURRENT_BUFFER;
break;
case VOLT_FIPS_186_NO_BUFFER:
/* If previousBytesFlag is VOLT_FIPS_186_NO_BUFFER, the variation
* is ALG (not CERTIFY). Also, we have the first block in the
* previousBytes buffer and the second block in the currentBytes
* buffer. Compare the two. If equal, error.
* If not equal, set previousBytesFlag to
* VOLT_FIPS_186_PREVIOUS_BUFFER and leave the two
* buffers alone.
*/
compareResult = Z2Memcmp (
fips186Ctx->previousBytes, fips186Ctx->currentBytes,
fips186Ctx->currentBytesLen);
fips186Ctx->previousBytesFlag = VOLT_FIPS_186_PREVIOUS_BUFFER;
break;
case VOLT_FIPS_186_PREVIOUS_BUFFER:
/* If previousBytesFlag is VOLT_FIPS_186_PREVIOUS_BUFFER, the
* variation is ALG (not CERTIFY). Also, we have the first block
* in the previousBytes buffer and the second block in the
* currentBytes buffer. We've already done the compare and we've
* already output the first block. Copy the currentBytes into the
* previousBytes and set previousBytesFlag to
* VOLT_FIPS_186_CURRENT_BUFFER. The currentBytesLen is 0, so
* reset it.
*/
Z2Memcpy (
fips186Ctx->previousBytes, fips186Ctx->currentBytes,
2 * FIPS_186_PRNG_OUTPUT_BLOCK_SIZE);
fips186Ctx->previousBytesFlag = VOLT_FIPS_186_CURRENT_BUFFER;
fips186Ctx->currentBytesLen = FIPS_186_PRNG_OUTPUT_BLOCK_SIZE;
if (fips186Ctx->primeQ == (VoltMpInt *)0)
fips186Ctx->currentBytesLen = 2 * FIPS_186_PRNG_OUTPUT_BLOCK_SIZE;
break;
default:
/* If previousBytesFlag is VOLT_FIPS_186_CURRENT_BUFFER, operate
* normally. Compare the two buffers, if equal, error, if not
* equal, copy current into previous. Leave previousBytesFlag
* alone.
*/
compareResult = Z2Memcmp (
fips186Ctx->previousBytes, fips186Ctx->currentBytes,
fips186Ctx->currentBytesLen);
Z2Memcpy (
fips186Ctx->previousBytes, fips186Ctx->currentBytes,
2 * FIPS_186_PRNG_OUTPUT_BLOCK_SIZE);
}
if (compareResult != 0)
return (0);
/* If we're building this for the FIPS shared library, we want to set
* the FIPS error.
*/
#if VOLT_BUILD == VOLT_BUILD_FIPS_SHARED
VOLT_SET_FNCT_LINE (fnctLine)
VoltSetFipsError (VT_ERROR_FIPS_DRNG_OUTPUT);
status = VT_ERROR_FIPS_DRNG_OUTPUT;
#else
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_RANDOM_OBJECT;
#endif /* VOLT_BUILD == VOLT_BUILD_FIPS_SHARED */
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, VT_ERROR_TYPE_PRIMARY, fnctLine,
"TestOutput", (char *)0)
return (status);
}
static int UpdateXKEY (
VoltLibCtx *libCtx,
VoltFips186PrngCtx *fips186Ctx
)
{
int status;
unsigned int count, sign;
unsigned char oneChar = 1;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* To update XKEY
* 1. XVAL = XKEY + XSEED
* 2. resultOne = Digest (XVAL)
* 3. XKEY = 1 + XKEY + resultOne
* 4. XVAL = XKEY + XSEED
* 5. resultTwo = Digest (XVAL)
* 6. XKEY = 1 + XKEY + resultTwo
* 7. (general) if no primeQ, result = (resultOne || resultTwo)
* 7. (gen X, K) result = (resultOne || resultTwo) mod primeQ
*/
/* Step 1. Use seedBuffer as a temp buffer to add without
* disturbing the XKEY buffer.
*/
Z2Memcpy (fips186Ctx->seedBuffer, fips186Ctx->xkey, fips186Ctx->byteSize);
AddBuffers (
fips186Ctx->xseed, fips186Ctx->byteSize,
fips186Ctx->seedBuffer, fips186Ctx->byteSize);
/* Step 2. XVAL is in the seedBuffer.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (fips186Ctx->digestObj);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
fips186Ctx->digestObj, fips186Ctx->seedBuffer, fips186Ctx->byteSize,
fips186Ctx->currentBytes, 2 * FIPS_186_PRNG_OUTPUT_BLOCK_SIZE, &count);
if (status != 0)
break;
fips186Ctx->currentBytesOffset = 0;
/* We assume that count (size of the digest) is not less than
* FIPS_186_PRNG_OUTPUT_BLOCK_SIZE.
*/
fips186Ctx->currentBytesLen = FIPS_186_PRNG_OUTPUT_BLOCK_SIZE;
/* Step 3.
*/
AddBuffers (
fips186Ctx->currentBytes, count, fips186Ctx->xkey, fips186Ctx->byteSize);
AddBuffers (&oneChar, 1, fips186Ctx->xkey, fips186Ctx->byteSize);
/* Step 4. Use seedBuffer as a temp buffer to add without
* disturbing the XKEY buffer.
*/
Z2Memcpy (fips186Ctx->seedBuffer, fips186Ctx->xkey, fips186Ctx->byteSize);
AddBuffers (
fips186Ctx->xseed, fips186Ctx->byteSize,
fips186Ctx->seedBuffer, fips186Ctx->byteSize);
/* Setp 5. XVAL is in the seedBuffer.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (fips186Ctx->digestObj);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
fips186Ctx->digestObj, fips186Ctx->seedBuffer, fips186Ctx->byteSize,
fips186Ctx->currentBytes + FIPS_186_PRNG_OUTPUT_BLOCK_SIZE,
FIPS_186_PRNG_OUTPUT_BLOCK_SIZE, &count);
if (status != 0)
break;
fips186Ctx->currentBytesLen += FIPS_186_PRNG_OUTPUT_BLOCK_SIZE;
/* Step 6.
*/
AddBuffers (
fips186Ctx->currentBytes + FIPS_186_PRNG_OUTPUT_BLOCK_SIZE, count,
fips186Ctx->xkey, fips186Ctx->byteSize);
AddBuffers (&oneChar, 1, fips186Ctx->xkey, fips186Ctx->byteSize);
/* If there is a prime, mod reduce.
*/
if (fips186Ctx->primeQ != (VoltMpInt *)0)
{
/* Step 7.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = fips186Ctx->mpCtx->OctetStringToMpInt (
0, fips186Ctx->currentBytes, fips186Ctx->currentBytesLen,
fips186Ctx->base);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = fips186Ctx->mpCtx->ModReduce (
fips186Ctx->base, fips186Ctx->primeQ, fips186Ctx->reduction);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = fips186Ctx->mpCtx->MpIntToOctetString (
fips186Ctx->reduction, &sign, fips186Ctx->currentBytes,
2 * FIPS_186_PRNG_OUTPUT_BLOCK_SIZE, &count);
if (status != 0)
break;
fips186Ctx->currentBytesLen = FIPS_186_PRNG_OUTPUT_BLOCK_SIZE;
if (count >= FIPS_186_PRNG_OUTPUT_BLOCK_SIZE)
break;
/* If the length of the reduction is less than the
* OUTPUT_BLOCK_SIZE, prepend 0's. Use sign as a temp variable.
*/
sign = FIPS_186_PRNG_OUTPUT_BLOCK_SIZE - count;
Z2Memmove (
fips186Ctx->currentBytes + sign, fips186Ctx->currentBytes, count);
Z2Memset (fips186Ctx->currentBytes, 0, sign);
}
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, (VtLibCtx)libCtx, status, 0, fnctLine, "UpdateXKEY", (char *)0)
return (status);
}
static void AddBuffers (
unsigned char *addend,
unsigned int addendLen,
unsigned char *sum,
unsigned int sumLen
)
{
unsigned int index, indexA, indexS;
unsigned char carry;
/* Paranoid programming, make sure addendLen is <= sumLen. The caller
* is supposed to make sure this never happens, but put this in
* anyway.
*/
if (addendLen > sumLen)
addendLen = sumLen;
/* Start at the end of each buffer.
*/
indexA = addendLen;
indexS = sumLen;
carry = 0;
for (index = 0; index < addendLen; ++index)
{
indexS--;
indexA--;
sum[indexS] += carry;
if (sum[indexS] < carry)
carry = 1;
else
carry = 0;
sum[indexS] += addend[indexA];
if (sum[indexS] < addend[indexA])
carry = 1;
}
/* If there are more sum bytes, propagate the carry. But only up to
* the most significant byte of sum. If there's still carry, then it
* is lost.
*/
if (indexS == 0)
return;
if (carry == 0)
return;
do
{
indexS--;
sum[indexS]++;
if (sum[indexS] != 0)
return;
} while (indexS != 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -