📄 rngtest.c
字号:
/*____________________________________________________________________________
RNGtest.c
Copyright (C) 2003,2004 PGP Corporation
All rights reserved.
FIPS 140-2 Operational Test/ Key Generation
$Id: RNGtest.c 48562 2006-10-16 20:48:55Z vinnie $
____________________________________________________________________________*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pgpErrors.h"
#include "pgpKeys.h"
#include "pgpPublicKey.h"
#include "pgpEncode.h"
#include "pgpUtilities.h"
#include "pgpRandomPool.h"
#include "pgpCFB.h"
#include "pgpMemoryMgr.h"
#include "pgpBigNum.h"
#include "optest.h"
/*
* Acquire entropy
*
* First try to get it from the random device on the system
* If that fails and the user is allowing interaction, prompt
* Otherwise we return an error
*
* Return Value:
* Out of entropy if this function times out
*/
PGPError
ConsoleAcquireEntropy(
PGPContextRef context,
PGPUInt32 entropyNeeded,
PGPUInt32 * pEntropyAcquired,
PGPBoolean bOutputProgress)
{
PGPError err = kPGPError_NoErr;
PGPUInt32 entropyAcquired = 0;
time_t start = 0;
time_t current = 0;
if (entropyNeeded == 0)
return (kPGPError_NoErr);
if (bOutputProgress)
OPTESTPrintF("\t%d more bits needed\n\tCollecting from system state",
entropyNeeded - entropyAcquired);
time (&start);
while (entropyAcquired < entropyNeeded)
{
entropyAcquired = PGPContextReserveRandomBytes (context, entropyNeeded);
err = PGPGlobalRandomPoolAddSystemState (); CKERR;
if (bOutputProgress)
OPTESTPrintF("."),fflush(stdout);
time (¤t);
if (current > (start + 10))
break;
}
if (bOutputProgress)
OPTESTPrintF(" OK\n");
if (entropyAcquired < entropyNeeded)
return (kPGPError_OutOfEntropy);
done:
if (IsntPGPError (err))
{
if (pEntropyAcquired)
*pEntropyAcquired = entropyAcquired;
}
return (err);
}
#define kRandomBuffSize 64
/*
Example of how to use the built-in PGP PRNG
*/
PGPError TestRNG(PGPContextRef context)
{
PGPError err = kPGPError_NoErr;
void * buffer = NULL;
PGPFlags flags;
PGPFileSpecRef seedFileSpec = kInvalidPGPFileSpecRef;
PGPUserValue userVal = 0;
PGPChar8 *tempDir = NULL;
/* example of how to create custom context, just for testing purpose */
#define kUserValue (PGPUserValue) 0x12345678
PGPContextRef context1 = kInvalidPGPContextRef;
PGPCustomContextInfo custom;
(void) context;
OPTESTPrintF("\tCreate Custom Memory Context\n" );
custom.sdkAPIVersion = kPGPsdkAPIVersion;
custom.userValue = kUserValue;
err = PGPNewMemoryMgr( 0, &custom.memoryMgr ); CKERR;
err = PGPNewContextCustom(&custom, &context1); CKERR;
err = PGPGetContextUserValue(context1, &userVal); CKERR;
// if(userVal != kUserValue) FAIL("Couldn't get context user value");
/* Test ContextTempDirectory */
err = PGPSetContextTempDirectory(context1, gOutputDirectory); CKERR;
err = PGPGetContextTempDirectory(context1, &tempDir);
OPTESTPrintF("\tContext TempDirectory = %s\n", tempDir);
#if 0
/* create filerefs to the Seedfile*/
err = PGPNewFileSpecFromFullPath(context1, "FIPSSEED.rnd", &seedFileSpec); CKERR;
/* specify new Seedfile*/
err = PGPSetRandSeedFile((PFLFileSpecRef) seedFileSpec); CKERR;
#endif
/* TE03.14.02 - Data storage management */
OPTESTPrintF("\tAllocating %d bytes of secure memory...",kRandomBuffSize );
buffer = PGPNewSecureData( PGPPeekContextMemoryMgr(context1), kRandomBuffSize, kPGPMemoryMgrFlags_None);
if(!buffer)
{
err = kPGPError_OutOfMemory;
goto done;
}
flags = PGPGetMemoryMgrDataInfo(buffer );
OPTESTPrintF("(");
if(flags & kPGPMemoryMgrBlockInfo_Valid) OPTESTPrintF(" OK");
if(flags & kPGPMemoryMgrBlockInfo_Secure) OPTESTPrintF(" Secure");
if(flags & kPGPMemoryMgrBlockInfo_NonPageable) OPTESTPrintF(" NonPageable");
OPTESTPrintF(")\n");
err = ConsoleAcquireEntropy(context1, kRandomBuffSize, NULL, TRUE); CKERR;
/* TE03.14.02 - Get random bytes */
OPTESTPrintF("\tFilling buffer with random data..." );
err = PGPContextGetRandomBytes(context1, buffer, kRandomBuffSize); CKERR;
OPTESTPrintF("\n");
dumpHex(buffer, kRandomBuffSize,0);
err = PGPReallocData(PGPPeekContextMemoryMgr(context1), &buffer, kRandomBuffSize+ 8, kPGPMemoryMgrFlags_None);
done:
OPTESTPrintF("\tZeroing and freeing buffer\n" );
if(buffer) PGPFreeData(buffer);
// dumpHex(buffer, kRandomBuffSize,0);
if( PGPFileSpecRefIsValid(seedFileSpec))
PGPFreeFileSpec(seedFileSpec);
if(tempDir)
PGPFreeData(tempDir);
if( PGPContextRefIsValid( context1 ) )
PGPFreeContext(context1);
return err;
}
/*
This example shows how to build an X9_31 PRNG using the PGPsdk API
*/
static PGPError addOne(PGPContextRef context, PGPByte* p, PGPUInt32 len)
{
PGPError err = kPGPError_NoErr;
PGPBigNumRef bn = kPGPInvalidBigNumRef ;
err = PGPNewBigNum(context, 0, &bn); CKERR;
err = PGPBigNumInsertBigEndianBytes(bn, p, 0, len); CKERR;
err = PGPBigNumAddQ(bn,1,bn); CKERR;
err = PGPBigNumExtractBigEndianBytes(bn, p,0,len); CKERR;
done:
if(bn)
PGPFreeBigNum(bn);
return err;
}
static PGPError runX931TDES3Test(
PGPContextRef context,
const int cycles,
const PGPByte* KEY,
const PGPByte* IV,
const PGPByte* DT,
PGPByte* R )
{
PGPSymmetricCipherContextRef cipher = kInvalidPGPSymmetricCipherContextRef;
PGPCFBContextRef cfb = kInvalidPGPCFBContextRef;
PGPError err = kPGPError_NoErr;
PGPByte TIME[8];
PGPByte T[8];
int i;
PGPSize t;
#define SALT_STRING "stupid is, as stupid does"
COPY( DT, TIME, 8 );
/* create and setup the cipher & CFB */
err = PGPNewSymmetricCipherContext(context, kPGPCipherAlgorithm_3DES, &cipher); CKERR;
err = PGPNewCFBContext(cipher, 1, &cfb); CKERR;
/*Note that the cipher was consumed by the PGPNewCFBContext call and
so if we want a valid ref to the cipher we have to ask for it */
PGPCFBGetSymmetricCipher(cfb, &cipher);
/* init CFB with IV and Key */
err = PGPInitCFB(cfb, KEY, IV); CKERR;
for(i = 0; i< cycles; i++)
{
/* T = E(TIMESTAMP) */
err = PGPSymmetricCipherEncrypt( cipher, TIME, T ); CKERR;
/* TIME + 1 for MCT */
addOne(context, TIME, 8);
/* Use SDK X.9.17 PNRG with supplied salt */
err = PGPCFBRandomCycle(cfb, T); CKERR;
}
/* get random bytes from the cipher. */
err = PGPCFBGetRandom(cfb, 8, R , &t); CKERR;
/* for testing only. no real purpose. */
err = PGPCFBRandomWash(cfb, SALT_STRING, sizeof(SALT_STRING));
done:
if( PGPCFBContextRefIsValid( cfb ) )
(void) PGPFreeCFBContext(cfb);
return err;
}
PGPError TestX9_31(PGPContextRef context)
{
PGPError err = kPGPError_NoErr;
/* ANSI X9.31 Known answer vectors */
PGPByte KEY[] = { 0x20, 0x0b, 0xf1, 0x46, 0x54, 0x70, 0xf7, 0xc8,
0x75, 0xfe, 0xb0, 0x10, 0x3e, 0xc1, 0x46, 0xfe,
0xcb, 0xe0, 0x85, 0x97, 0x58, 0x5e, 0xce, 0xad };
PGPByte IV[] = { 0x4c, 0x56, 0xb2, 0xe2, 0x77, 0x7a, 0x9b, 0x68 };
PGPByte DT[] = { 0xed, 0x05, 0xaa, 0xe2, 0xf5, 0xf9, 0xe6, 0x23 };
PGPByte KAT[] = { 0x98, 0xe6, 0xdd, 0xe4, 0x22, 0xe3, 0xea, 0x5e };
PGPByte R[8];
OPTESTPrintF(" Starting X9.31 cycle\n");
err = runX931TDES3Test( context, 10000, KEY, IV, DT, R ); CKERR;
/* check against orginal plain-text */
err = pgpMemoryEqual(R, KAT, sizeof(KAT)) ? kPGPError_NoErr : kPGPError_SelfTestFailed;
if( IsPGPError(err) )
{
OPTESTPrintF("\n\t\tANSI X9.31 Known answer\n\t\t expected:\t" );
dumpLong(R, sizeof(R));
OPTESTPrintF("\t\t produced:\t");
dumpLong(KAT, sizeof(KAT) );
OPTESTPrintF("\n");
}
done:
return err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -