?? fipsprime.c
字號(hào):
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "mpint.h"
#include "prime.h"
#include "errorctx.h"
int VoltGeneratePrimeFips (
unsigned int primeSizeBits,
VtRandomObject random,
unsigned char *SEED,
unsigned int *seedLen,
VoltMpInt *prime
)
{
int status, count;
unsigned int bufferSize, digestLen, index, limit;
unsigned int bitMask, bitSet, isPrime;
VoltMpIntCtx *mpCtx = (VoltMpIntCtx *)(prime->mpCtx);
VoltLibCtx *libCtx = (VoltLibCtx *)(mpCtx->voltObject.libraryCtx);
VtAlgorithmObject sha1 = (VtAlgorithmObject)0;
unsigned char *buffer = (unsigned char *)0;
unsigned char digest[40];
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* How many bytes do we generate.
*/
bufferSize = (primeSizeBits + 7) / 8;
*seedLen = bufferSize;
do
{
/* Currently, the toolkit is supporting only 160 bit primes to be
* generated using the FIPS technique
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_PARAM_LENGTH;
if (primeSizeBits != 160)
break;
/* Build a buffer to hold the starting point.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
/* Create a mask for the first byte. Depending on the bit length,
* we may want to trim some bits off the top.
*/
bitSet = primeSizeBits % 8;
if (bitSet == 0)
bitSet = 8;
bitMask = 0xff >> (8 - bitSet);
/* Make sure the msbit is set. Create a value to OR with the first
* byte that will set the msbit.
*/
bitSet = 1 << (bitSet - 1);
/* Build the SHA-1 digest object to be used in step 2 below.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, VtAlgorithmImplSHA1, (Pointer)0, &sha1);
if (status != 0)
break;
count = 0;
isPrime = 1;
do
{
/* Step 1: "Choose an arbitrary sequence ... call it SEED."
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGenerateRandomBytes (random, SEED, bufferSize);
if (status != 0)
break;
/* Step 2: Compute U.
*/
Z2Memcpy (buffer, SEED, bufferSize);
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (sha1);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
sha1, buffer, bufferSize, digest, sizeof (digest), &digestLen);
if (status != 0)
break;
/* Add 1 to SEED (don't carry beyond the most significant byte).
*/
for (index = bufferSize; index > 0; --index)
{
buffer[index - 1] += 1;
if (buffer[index - 1] != 0)
break;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (sha1);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
sha1, buffer, bufferSize, digest + digestLen,
sizeof (digest) - digestLen, &digestLen);
if (status != 0)
break;
/* XOR the two digests.
*/
limit = digestLen;
if (digestLen > bufferSize)
limit = bufferSize;
for (index = 0; index < limit; ++index)
buffer[index] = digest[index] ^ digest[index + digestLen];
/* Step 3: Form q.
*/
buffer[0] &= (unsigned char)bitMask;
buffer[0] |= (unsigned char)bitSet;
buffer[bufferSize - 1] |= 1;
/* Set the MpInt to this value.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->OctetStringToMpInt (0, buffer, bufferSize, prime);
if (status != 0)
break;
/* Step 4: Run Rabin-Miller on this value.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltRabinMillerTest (
prime, primeSizeBits, VOLT_RABIN_MILLER_COUNT_186_2,
random, &isPrime);
if (status != 0)
break;
/* If this came back prime, we're done.
*/
if (isPrime != 0)
break;
/* Step 5: The Rabin-Miller test indicates that the number is not
* prime, get a new random starting point. But first, don't run
* this test forever. Try up to 1000000 times.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_NO_PRIME_FOUND;
count++;
if (count > 1000000)
break;
} while (1);
} while (0);
VtDestroyAlgorithmObject (&sha1);
Z2Memset (digest, 0, sizeof (digest));
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR_COMPARE (
status, (VtLibCtx)libCtx, status, errorType, fnctLine,
"VoltGeneratePrimeFips", (char *)0)
return (status);
}
void VoltAddValueToBuffer (
unsigned char *buffer,
unsigned int bufferLen,
UInt32 increment
)
{
unsigned int indexB, indexI;
unsigned char carry, val;
unsigned char vector[4];
VOLT_SET_UINT32 (increment, vector)
/* Add the four words of the increment to the low four words of the
* buffer.
*/
carry = 0;
for (indexI = 4, indexB = bufferLen; indexI > 0; --indexI, --indexB)
{
val = carry + vector[indexI - 1];
if (val >= carry)
carry = 0;
buffer[indexB - 1] += val;
if (buffer[indexB - 1] < val)
carry = 1;
}
/* If there's no carry, we're done.
*/
if (carry == 0)
return;
/* Propagate the carry through the buffer (ignoring any carry beyond
* the most significant byte.
*/
for (; indexB > 0; --indexB)
{
buffer[indexB - 1] += 1;
if (buffer[indexB - 1] != 0)
break;
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -