Recipes for Cryptography, Authentication, Networking, Input Validation & More John Viega, Zachary Girouard & Matt Messier Secure Programming Cookbook
Text Previews (text result may be not accurate) Secure
Programming
Cookbook
Unix & Windows
Secure Programming Cookbook
for C and C++
Secure Programming Cookbook
for C and C++
John Viega and Matt Messier
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
568
Chapter11
Security-criticalapplicationsoftenrequirewell-chosenrandomnumbers,forpur-
posesrangingfromcryptographickeygenerationtoshufflingavirtualdeckofcards.
Eventhoughproblemswithrandomnumbersseemasiftheyshouldbefewandfar
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Solution
Moreproperly,thesearenoncryptographicpseudo-randomnumbergenerators.
Youshouldgenerallyassumethatanattackercouldpredicttheoutputofsucha
Thesetakeasinglesecureseedandproduceasmanyunguessablerandomnum-
bersfromthatseedasnecessary.Suchasolutionshouldbesecureformostuses
Chapter11:Random Numbers
Notethatcryptographicpseudo-randomnumbergeneratorsalwaysproduceaniden-
ticalstreamofoutputwhenidenticallyseeded.Ifyouwishtorepeatastreamof
numbers,youshouldavoidreseedingthegenerator(oryouneedtodotheexact
Mostcommonrandomnumbergenerators,Žwhichwewillcall
pseudo-randomnumbergenerators
,arenotsecure.Theystartwithaseed(which
needstoberandominandofitselftohaveanychanceofsecurity)andusethatseed
toproduceastreamofnumbersthatlookrandomfromthepointofviewofastatisti-
Fromthepointofviewofagoodcryptographer,though,thenumbersproducedby
suchageneratorarenotsecure.Generally,noncryptographicgeneratorsleakinfor-
mationabouttheirinternalstatewitheachoutput,meaningthatagoodcryptogra-
phercanstartpredictingoutputswithhighaccuracyafterseeingafewrandom
numbers.Inarealsystem,yougenerallydonotevenneedtoseetheoutputsdirectly,
insteadinferringinformationabouttheoutputsfromthebehavioroftheprogram
(whichisgenerallymadeeveneasierwithabitofreverseengineeringofthepro-
Traditionalnoncryptographicpseudo-randomnumbergeneratorsincludethe
rand()
random()
functionsyoudexpecttoseeinmostlibraries(so-calledlinearcongru-
entialgenerators).OthernoncryptographicgeneratorsincludetheMersenne
TwisterŽandlinearfeedbackshiftregisters.Ifarandomnumbergeneratorisnot
advertisedasacryptographicrandomnumbergenerator,anditdoesnotoutput
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
thebyteiseven,hereducesthenumberofguessesnecessaryto2
(128),inwhich
Wecanhavefractionalbitsofentropy.Ifwehaveonebit,andithasa25%chanceof
Inpublickeycryptography,
-bitkeyscontainfarfewerthan
bitsof
entropy.Thatisbecausetherearenot2
possiblekeys.Forexample,
inRSA,wearemoreorlesslimitedbythenumberofprimesthatare
Chapter11:Random Numbers
Finally,youneedtorealizethatevenproperlyusedcryptographicpseudo-random
numbergeneratorsareonlygoodforacertainnumberofbytesofoutput,though
IfabreakintheunderlyingPRNGalgorithmweretobefound,itmightbepossible
Therefore,ifyouaregeneratingveryimportantdata,suchaslong-termcrypto-
graphickeys,generatethosekeysbytakingdatadirectlyfromanentropysourceif
Tips on Collecting Entropy
€Makesurethatanydatacomingfromanentropy-producingsourceispostpro-
cessedwithcryptographytoremoveanylingeringstatisticalbiasandtohelp
ensurethatyourdatahasatleastasmanybitsofentropyinputasbitsyouwant
€Makesureyouuseenoughentropytoseedanypseudo-randomnumbergenera-
€Whenchoosingapseudo-randomnumbergenerator,makesuretopickonethat
explicitlyadvertisesthatitiscryptographicallystrong.Ifyoudonotseetheword
cryptographicŽanywhereinassociationwiththealgorithm,itisprobablynot
€WhenselectingaPRNG,prefersolutionswitharefereedproofofsecurity
bounds.Countermode,inparticular,comeswithsuchaproof,sayingthatif
youuseablockcipherbitwith128-bitkeysand128-bitblocksseededwith128
bitsofpureentropy,andifthecipherisapseudo-randompermutation,thegen-
€Usepostprocessedentropyforseedingpseudo-randomnumbergeneratorsor,if
available,forpickinghighlyimportantcryptographickeys.Foreverythingelse,
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using a Generic API for Randomness and Entropy
|
573
See Also
11.2Using a Generic API for Randomness and
Entropy
Problem
Chapter11:Random Numbers
Thefunctions
spc_keygen()
spc_entropy()
shouldcryptographi-
callypostprocess(whiten)anyentropytheyusebeforeoutputtingit,if
thatsnotalreadydonebytheunderlyingentropysources.Often,it
willbedoneforyou,butitwillnothurttodoitagainifyouarenot
See Also
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using the Standard Unix Randomness Infrastructure
|
575
11.3Using the Standard Unix Randomness
Infrastructure
Problem
Solution
OnmostmodernUnixsystems,therearetwodevicesfromwhichyoucanread:
,whichisexpectedtoproduceentropy,and
,whichisexpected
toprovidecryptographicallysecurepseudo-randomvalues.Inreality,theseexpecta-
Ifyouneedacryptographicallystrongrandomnumbersourcethatis
Chapter11:Random Numbers
dontthinkyoushouldworryaboutthisissueinpractice.(Therearealmostalways
Second,dependingontheoperatingsystem,theentropyproducedby
maybereusedby
.Whilefew(ifany)Unixplatformstrytoguaranteea
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using the Standard Unix Randomness Infrastructure
|
577
Chapter11:Random Numbers
spc_rand()
byreadingfrom
.Finally,wewillimplement
spc_keygen()
byreadingasmuchdataaspossiblefrom
inanonblockingfashion,then
Notethatweneedtoopen
ontwofiledescriptors,oneblockingand
onenot,sothatwemayavoidraceconditionswhere
spc_keygen()
expectsafunc-
tiontobenonblockingbut
spc_entropy()
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using the Standard Unix Randomness Infrastructure
|
579
if (errno == EINTR) continue;
Chapter11:Random Numbers
11.4Using the Standard Windows Randomness
Infrastructure
Problem
Solution
CryptGenRandom()
unlessyouabsolutelyneedentropy,inwhichcaseseeRecipe
CryptAcquireContext()
Numberofbytesofrandomdatarequired.Theoutputbuffermustbeatleast
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using an Application-Level Generator
|
581
if (!hProvider) spc_rand_init();
Solution
Forgeneral-purposeuse,werecommendapseudo-randomnumbergeneratorbased
ontheAESencryptionalgorithmrunincounter(CTR)mode(seeRecipe5.9).This
Chapter11:Random Numbers
Streamciphersareactuallycryptographicpseudo-randomnumbergenerators.One
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using an Application-Level Generator
|
583
attacksarearealisticthreat,youwillusuallyhavefarbiggerthreats,andmitigating
Thereisalotthatcangowrongwhenusingapseudo-randomnumbergenerator.
Comingupwithagoodconstructturnsouttobetheeasypart.Herearesomethings
€Pseudo-randomnumbergeneratorsneedtobeseededwithanadequateamount
ofentropy;otherwise,theyarestillpotentiallypredictable.Werecommendat
least80bits.Seethevariousrecipeselsewhereinthischapterforinformationon
€Becarefultopayattentiontothemaximumnumberofoutputsageneratorcan
producebeforeitwillneedtobereseededwithnewentropy.Atsomepoint,gen-
eratorsstarttoleakinformationandwillgenerallyfallintoacycle.Note,
though,thatfortheconfigurationswepresent,youwillprobablyneverneedto
worryaboutthelimitinpractice.Forexample,thegeneratorbasedonAES-128
leaksabitofinformationafter2
16-byteblocksofoutput,andcyclesafter2
€Whenaddingentropytoasystem,itisbesttocollectalotofentropyandseed
allatonce,insteadofseedingalittlebitatatime.Wewillillustratewhyby
example.Supposethatyouseedageneratorwithonebitofentropy.Anattacker
hasonlyonebittoguess,whichcanbedoneaccuratelyaftertwooutputs.Ifthe
Chapter11:Random Numbers
Theseedshouldbeatleastaslargeasthekeysizeofthecipher,becauseitwillbe
usedtokeyablockcipher.Inaddition,itisusefultohaveadditionalseeddatathat
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using an Application-Level Generator
|
585
Chapter11:Random Numbers
prng-ix = 0; prng-kl = kl; SPC_BCPRNG_UNLOCK();
SPC_BCPRNG_LOCK();
prng-ix %= SPC_BLOCK_SZ; } while (l = SPC_BLOCK_SZ) { SPC_DO_ENCRYPT(&(prng-ks), prng-ctr, p); spc_increment_counter(prng); p += SPC_BLOCK_SZ; l -= SPC_BLOCK_SZ; } if (l) { SPC_DO_ENCRYPT(&(prng-ks), prng-ctr, prng-lo); spc_increment_counter(prng); prng-ix = l; while (l--) p[l] = prng-lo[l]; } SPC_BCPRNG_UNLOCK();
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using an Application-Level Generator
|
587
Using a stream cipher as a generator
Aswementioned,streamciphersarethemselvespseudo-randomnumbergenera-
tors,wherethekey(andtheinitializationvector,ifappropriate)constitutestheseed.
Ifyouareplanningtousesuchacipher,westronglyrecommendtheSNOW2.0
BecauseofthepopularityoftheRC4cipher,weexpectthatpeoplewillprefertouse
RC4,eventhoughitdoesnotlookasgoodasSNOW.TheRC4streamcipherdoes
makeanacceptablepseudo-randomnumbergenerator,anditisincrediblyfastifyou
donotrekeyfrequently(thatisparticularlyusefulifyouexpecttoneedaheckofa
lotofnumbers).Ifyoudorekeyfrequentlytoavoidbacktrackingattacks,ablock
RC4requiresalittlebitofworktouseproperly,givenastandardAPI.First,most
APIswantyoutopassindatatoencrypt.Becauseyouwantonlytherawkeystream,
youmustalwayspassinzeros.Second,besuretouseRC4inasecuremanner,as
IfyourRC4implementationhastheAPIdiscussedinRecipe5.23,seedingitasa
pseudo-randomnumbergeneratoristhesameaskeyingthealgorithm.RC4can
BecauseoflimitationsinRC4,youshouldthrowawaythefirst256
Afterencrypting256bytesandthrowingtheresultsaway,youcanthen,givenan
Chapter11:Random Numbers
#define SPC_RC4RNG_UNLOCK() ReleaseMutex(hSpcRC4RNGMutex)
unsigned char *p = buf;#ifdef WIN32 if (!hSpcRC4RNGMutex) hSpcRC4RNGMutex = CreateMutex(0, FALSE, 0);#endif SPC_RC4RNG_LOCK();
SPC_RC4RNG_UNLOCK();
RC4isonlybelievedtobeastrongsourceofrandomnumbersfor
about2
outputs.Afterthat,westronglyrecommendthatyoureseed
itwithnewentropy.Ifyourapplicationwouldnotconceivablyuse
thatmanyoutputs,itshouldgenerallybeokaynottocheckthatcon-
Using a generator based on a cryptographic hash function
Themostcommonmistakemadewhentryingtouseahashfunctionasacrypto-
graphicpseudo-randomnumbergeneratoristocontinuallyhashapieceofdata.
Suchanapproachgivesawaythegeneratorsinternalstatewitheveryoutput.For
example,supposethatyourinternalstateissomevalueX,andyougenerateandout-
putYbyhashingX.Thenexttimeyouneedrandomdata,rehashingXwillgivethe
sameresults,andanyattackerwhoknowsthelastoutputsfromthegeneratorcan
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using an Application-Level Generator
|
589
Oneverysafewaytouseacryptographichashfunctioninacryptographicpseudo-
randomnumbergeneratoristouseHMACincountermode,asdiscussedinRecipe
6.10.HereweimplementageneratorbasedontheHMAC-SHA1implementation
fromRecipe6.10.YoushouldbeabletoadaptthiscodeeasilytoanyHMACimple-
unsigned char lo[MAC_OUT_SZ]; /* Leftover block of output */ int ix; /* index into lo. */} SPC_MPRNG_CTX;#ifndef WIN32static pthread_mutex_t spc_mprng_mutex = PTHREAD_MUTEX_INITIALIZER;#define SPC_MPRNG_LOCK() pthread_mutex_lock(&spc_mprng_mutex)
#define SPC_MPRNG_UNLOCK() pthread_mutex_unlock(&spc_mprng_mutex)
#define SPC_MPRNG_LOCK() WaitForSingleObject(hSpcMPRNGMutex, INFINITE)
#define SPC_MPRNG_UNLOCK() ReleaseMutex(hSpcMPRNGMutex)
Chapter11:Random Numbers
SPC_MPRNG_UNLOCK();
SPC_MPRNG_LOCK();
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Reseeding a Pseudo-Random Number Generator
|
591
Ifyourhashfunctionproduces
-bitoutputsandhasnopracticalweaknesses,donot
usethegeneratorafteryouruntheMACmorethan2
times.Forexample,with
SHA1,thisgeneratorshouldbenotbeaproblemforatleast2
20bytes.Inprac-
Tobindthiscryptographicpseudo-randomnumbergeneratortotheAPIinRec-
ipe11.2,youcanuseasingleglobalgeneratorcontextthatyouseedin
init()
Chapter11:Random Numbers
TherearetwocommonreasonswhyyoumaywanttoreseedaPRNG.First,your
threatmodelmayincludethepossibilityoftheinternalstateofyourPRNGbeing
compromised,andyouwanttopreventagainstanattackersbeingabletofigureout
numbersthatwereoutputbeforethestatecompromise.Reseeding,ifdoneright,
essentiallytransformstheinternalstateinawaythatpreservesentropywhilemak-
ingitessentiallyimpossibletobacktrack.Protectingagainstbacktrackingattackscan
Second,youmaywanttoaddentropyintothestate.Thiscouldserveanumberof
purposes.Forexample,youmightwanttoaddentropytothesystem.Remember,
however,thatcryptographicgeneratorshaveamaximumamountofentropythey
Whenavailable,however,reseedingwithentropyisagoodconservativemeasure,for
severalreasons.Foronereason,ifyouhaveunderestimatedtheamountofentropy
thatageneratorhas,addingentropyisagoodthing.Foranother,ifthegeneratorhas
lostanyentropy,newentropycanhelpreplenishit.Suchentropylossisnatural
Whenaddingentropytoasystem,itisbesttocollectalotofentropy
andseedallatonce,insteadofseedingalittlebitatatime.Wewill
illustratewhybyexample.Supposeyouseedageneratorwithonebit
ofentropy.Anattackerhasonlyonebittoguess,whichcanbedone
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Reseeding a Pseudo-Random Number Generator
|
593
1.Figureouthowbigaseedyouneed.Attheveryleast,youneedaseedthatisas
manybitsinlengthasbitsofentropyyouthinkareinthegenerator.Generally,
thiswillbeatleastaslargeasthekeysizeoftheunderlyingprimitive(ortheout-
2.Ifyouneedtointroducenewentropy,properlycompressthedatacontaining
entropy.Inparticular,youmusttransformthedataintoaseedoftheproper
size,withminimallossofentropy.Oneeasywaytodothatistoprocessthe
stringwithacryptographichashfunction(truncatingthehashoutputtothe
desiredlength,ifnecessary).ThenXORthecompressedentropywiththeseed
3.Takethevalueanduseittoreseedthegenerator.Ifyouareusingacounter-
Chapter11:Random Numbers
11.7Using an Entropy Gathering
Daemon…Compatible Solution
Problem
Yourapplicationneedsrandomness,andyouwantittobeabletorunonUnix-based
platformsthatlackthe
devicesdiscussedinRecipe
Solution
Useathird-partysoftwarepackagethatgathersandoutputsentropy,suchasthe
EntropyGatheringandDistributionSystem(EGADS).ThenusetheEntropyGather-
ingDaemon(EGD)interfacetoreadentropy.EGDisatoolforentropyharvesting
WhenimplementingourrandomnessAPIfromRecipe11.2,useentropygathered
overtheEGDinterfaceinplaceswhereentropyisneeded;then,toimplementthe
restoftheAPI,usedatafromthatinterfacetoseedanapplication-levelcrypto-
Afewentropycollectionsystemsexistasprocessesoutsidethekernelanddistribute
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using an Entropy Gathering Daemon…Compatible Solution
|
595
Querytheamountofentropybelievedtobeavailable.Thisinformationisnotat
alluseful,particularlybecauseyoucannotuseitinanydecisiontoreaddata
Readdataifavailable.Thiscommandtakesasingle-byteargumentspecifying
howmanybytesofdatashouldberead,ifthatmuchdataisavailable.Ifnot
Chapter11:Random Numbers
process.WhileEGADSimplementstheEGDinterface,itignorestheentropyesti-
matesuppliedbytheuser.Itdoesmixtheentropyintoitsstate,butitassumesthatit
Thefollowingcodeimplementsthe
spc_entropy()
spc_keygen()
fromRecipe11.2usingtheEGDinterface.Weomit
spc_rand()
butassumethatit
exists(itiscalledby
spc_keygen()
whenappropriate).Toimplement
spc_rand()
Whenimplementing
spc_entropy()
spc_keygen()
,wedonotcryptographically
postprocesstheentropytothwartstatisticalanalysisifwedonothaveasmuch
entropyasestimated,asyoucangenerallyexpectserversimplementingtheEGD
interfacetodothis(EGADScertainlydoes).Ifyouwanttobeabsolutelysure,you
Notethatthefollowingcoderequiresyoutoknowinadvancethefileonthefilesys-
temthatimplementstheEGDinterface.ThereisnostandardplacetolookforEGD
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using an Entropy Gathering Daemon…Compatible Solution
|
597
Chapter11:Random Numbers
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
} while (nb == -1);
See Also
€EGADS by Secure Software, Inc.:
€Recipes 2.4, 11.2, 11.3, 11.5, 11.16, 11.19
Chapter11:Random Numbers
onthestrengthoftheAEScryptographicalgorithm.EGADSdoesagoodjobofpro-
tectingagainstcompromisedentropysources,whichotherPRNGstendnottodo.It
alsoprovidesagoodamountofprotectionagainstbacktrackingattacks,meaning
rentlyavailabletosatisfytherequest,thisfunctionwillblockuntilthereis.Itssigna-
spc_entropy()
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Numberofbytesofentropythatshouldbewrittenintotheoutputbuffer.You
mustbesurethattheoutputbufferissufficientlylargetoholdtherequested
Ifanyerroroccurs,anerrorcodewillbestoredinthisargument.Avalueof0
indicatesthatnoerroroccurred;otherwise,oneofthe
constantsdefined
Chapter11:Random Numbers
egads_randlong()
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Using the OpenSSL Random Number API
|
603
See Also
€EGADS by Secure Software, Inc.:
€Recipe 11.2
11.9Using the OpenSSL Random Number API
Problem
ManyfunctionsintheOpenSSLlibraryrequiretheuseoftheOpenSSLpseudo-ran-
Chapter11:Random Numbers
anyway.Youcanuseanyofthesourceswehavediscussedelsewhereinthischapter
forseedingtheOpenSSLPRNG.MultipleAPIfunctionsareavailablethatallowseed
Onesuchfunctionis
RAND_seed()
,whichallowsyoutopassinarbitrarydatathat
RAND_bytes()
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Ifthegeneratorisnotseededwithenoughentropy,thisfunctioncouldproduceout-
Donot,underanycircumstances,usetheAPIfunction,
bytes()
.ItisnotacryptographicallystrongPRNGandthereforeis
notworthusingforanythingthathasevenaremotepossibilityof
Youcanimplement
spc_rand()
,thecryptographicpseudo-randomnessfunction
fromRecipe11.2,bysimplycalling
RAND_bytes()
andabortingifthatfunction
Chapter11:Random Numbers
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Inallcases,youwillstartwithafunctionthatgivesyouarandomunsignednumber
thatcanbeanyvalue,suchas
spc_rand_uint()
fromRecipe11.10.Youwillmold
Someprogrammersmayexpectthisfunctiontoexcludetheupper
limitasapossiblevalue;however,weimplementthisfunctioninsuch
if (max min) abort(); /* Do your own error handling if appropriate.*/
rado = spc_rand_uint();
Chapter11:Random Numbers
Youmightworryaboutasituationwhereperformancesuffersbecausethiscodehas
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Solution
Becauseofthewaythatfloating-pointnumbersarestored,simplycastingbitstoa
Chapter11:Random Numbers
Inallcases,westartwithanumberwithuniformdistributionusingtheAPIfrom
Notethatthesefunctionsusemathoperationsdefinedinthestandardmathlibrary.
Onmanyplatforms,youwillhavetolinkagainsttheappropriatelibrary(usuallyby
myr1 = spc_rand_real();
myr2 = spc_rand_real();
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Chapter11:Random Numbers
while (--len)
*p++ = (char)spc_rand_range(33, 126);
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Compressing Data with Entropy into a Fixed-Size Seed
|
613
See Also
11.16Compressing Data with Entropy into a
Fixed-Size Seed
Problem
Youarecollectingdatathatmaycontainentropy,andyouwillneedtooutputa
fixed-sizeseedthatissmallerthantheinput.Thatis,youhavealotofdatathathasa
Itisagoodideatouseacryptographicalgorithmtocompressthedatafromthe
entropysourceintoaseedoftherightsize.Thishelpspreserveentropyinthedata,
uptotheoutputsizeofthemessagedigestfunction.Ifyouneedfewerbytesfora
seedthanthedigestfunctionproduces,youcanalwaystruncatetheoutput.Inaddi-
tion,cryptographicprocessingeffectivelyremovesanypatternsinthedata(assum-
ingthatthehashfunctionisapseudo-randomfunction).Patternsinthedatacan
helpfacilitatebreakinganentropysource(inpartorinfull),particularlywhenthat
Chapter11:Random Numbers
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Statistically Testing Random Numbers
|
615
Itwouldbeniceifyoudidnothavetocollectentropyeverytimeaprogramstartsup
Chapter11:Random Numbers
FIPS140testsareusefulforprovingthatastreamofrandomnumbers
areweak,butthetestsdontdemonstrateatallwhenthenumbersare
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Statistically Testing Random Numbers
|
617
Forthisreason,wethinkthefullsuiteofFIPS140-1testsisthewaytogoanytime
Chapter11:Random Numbers
int spc_fips_poker(unsigned char data[FIPS_NUMBYTES]) {
int i;
for (i = 0; i FIPS_NUMBYTES; i++) {
counts[data[i] & 0xf]++;
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Statistically Testing Random Numbers
|
619
unsigned char curr;
for (cur_val = i = runsz = 0; i FIPS_NUMBYTES; i++) {
curr = data[i];
Chapter11:Random Numbers
Thesecondoutputisalsosavedandisthencomparedtothethirdblock.Thispro-
Thefollowing(non-thread-safe)codeaddsaFIPS-compliantwrappertothe
entropy()
functionfromRecipe11.2(notethatthisassumesthat
spc_entropy()
doesnotcryptographicallypostprocessitsdata,becauseotherwisethetestisallbut
static char *last = b1, *next = b2; char *p = outbuf; if (bufsz == -1) {
while (n = RNG_BLOCK_SZ) { /* Old next becomes last here */ *next ^= *last; *last ^= *next; *next ^= *last; spc_entropy(next, RNG_BLOCK_SZ); for (i = 0; i RNG_BLOCK_SZ; i++) if (next[i] != last[i]) goto okay; abort();
) goto okay2; abort();
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Performing Entropy Estimation and Management
|
621
See Also
€NISTCryptographicModuleValidationProgramhomepage:
€Recipe 11.2
11.19Performing Entropy Estimation and
Problem
Chapter11:Random Numbers
example,supposethatyouwanttocollecta128-bitseed,andyoureadkeyboard
inputandalsoreadseparatelyfromafasthardwarerandomnumbergenerator.With
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Performing Entropy Estimation and Management
|
623
Onethingyoushoulddotoavoidintroducingsecurityproblemsby
underestimatingentropyisaggregateeachentropysourceindepen-
Chapter11:Random Numbers
Particularlywhenanattackermayhavelocalaccesstoamachine,itcanbeahope-
lesstasktofigureoutwhatallthepossiblechannelsare.Makingthingsdifficultis
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Performing Entropy Estimation and Management
|
625
youuseaseedfile,youcanjustcollectentropyatinstalltime,atwhichpointinter-
Entropy in timestamps
Chapter11:Random Numbers
However,inpractice,eventhatnumberistoohighbyabit,becausewealwaysknow
thatthemostsignificantbitwecountisa1.Onlytherestofthedataisreallylikely
Inpractice,tocalculatethemaximumamountofentropywebelievewemayhavein
thedelta,wefindthemostsignificant1bitinthevalueandcountthenumberofbits
fromthatpointforward.Forexample,therearefivebitsfollowingthemostsignifi-
cant1bitin
,sowewouldcountsix.Thisisthesameastakingthefloorofthe
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Performing Entropy Estimation and Management
|
627
Chapter11:Random Numbers
However,ifyouhaveamoreliberalthreatmodel,theremaybesomeentropyinthe
positionofthemouse.Unfortunately,mostmousemovementsfollowsimpletrajec-
torieswithverylittleentropy.Themostentropyoccurswhenthepointerreachesthe
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Performing Entropy Estimation and Management
|
629
withahigh-resolutionclock(i.e.,onerunningintheGHzrange).Ifyourclockhas
Chapter11:Random Numbers
11.20Gathering Entropy from the Keyboard
Problem
Youneedentropyinalow-entropyenvironmentandcanprompttheusertotypein
Solution
OnUnix,readdirectlyfromthecontrollingterminal(
).OnWindows,pro-
cessallkeyboardevents.Mixintoanentropypoolthekeypressed,alongwiththe
timestampatwhicheachonewasprocessed.Estimateentropybaseduponyour
Therecanbeareasonableamountofentropyinkeypresses.Theentropycomesnot
simplyfromwhichkeyispressed,butfromwheneachkeyispressed.Infact,mea-
suringwhichkeyispressedcanhaveverylittleentropyinit,particularlyinan
embeddedenvironmentwherethereareonlyafewkeys.Mostoftheentropywill
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from the Keyboard
|
631
Collecting entropy from the keyboard on Unix
Chapter11:Random Numbers
stdi;o.h0;#include stdio.h
#define HASH_OUT_SZ 20
#define OVERHEAD_CHARS 7
void spc_raw(int fd, struct termios *saved_opts) {
struct termios new_opts;
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from the Keyboard
|
633
} else
Chapter11:Random Numbers
Collecting entropy from the keyboard on Windows
TocollectentropyfromthekeyboardonWindows,wewillstartbybuildingadia-
logthatdisplaysabriefmessageadvisingtheusertotyperandomcharactersonthe
keyboarduntilenoughentropyhasbeencollected.Thedialogwillalsocontaina
progressbarandanOKbuttonthatisinitiallydisabled.Asentropyiscollected,the
progressbarwillbeupdatedtoreporttheprogressofthecollection.Whenenough
entropyhasbeencollected,theOKbuttonwillbeenabled.ClickingtheOKbutton
Callthefunction
SpcGatherKeyboardEntropy()
tobegintheprocessofcollecting
entropy.ItrequirestwoadditionalargumentstoitsUnixcounterpart,
keyboard_entropy()
Applicationinstancehandlenormallyobtainedfromthefirstargumentto
WinMain()
Handletothedialogsparentwindow.Itmaybespecifiedas
,inwhichcase
Numberofbytesofentropytoplaceintotheoutputbuffer.Theoutputbuffer
mustbesufficientlylargetoholdtherequestedamountofentropy.Thenumber
ofbytesofentropyrequestedshouldnotexceedthesizeofthehashfunction
used,whichisSHA1inthecodeprovided.SHA1producesa160-bitor20-byte
hash.Iftherequestedentropyissmallerthanthehashfunctionsoutput,the
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from the Keyboard
|
635
SpcGatherKeyboardEntropy()
usestheCryptoAPItohashthedatacollectedfromthe
keyboard.Itfirstacquiresacontextobject,thencreatesahashobject.Aftertheargu-
mentsarevalidated,thedialogresourceisloadedbycalling
CreateDialog()
,which
createsamodelessdialog.Thedialogiscreatedmodelesssothatkeyboardmessages
canbecaptured.Ifamodaldialogiscreatedusing
DialogBox()
oroneofitssiblings,
Oncethedialogissuccessfullycreated,themessage-handlingloopperformsnormal
messagedispatching,calling
IsDialogMessage()
tododialogmessageprocessing.
Keyboardmessagesarecapturedinthelooppriortocalling
IsDialogMessage()
,how-
ever.Thatsbecause
IsDialogMessage()
causesthemessagestobetranslatedanddis-
Whenakeyispressed,a
messagewillbereceived,whichcontainsinfor-
mationaboutwhichkeywaspressed.Whenakeyisreleased,a
willbereceived,whichcontainsthesameinformationaboutwhichkeywasreleased
containsaboutakeypress.Thekeyboardscancodeisextractedfrom
themessage,combinedwithatimestamp,andfedintothehashobject.Ifthecur-
rentscancodeisthesameasthepreviousscancode,itisnotcountedasentropybut
isaddedintothehashanyway.Asotherkeystrokesarecollected,theprogressbaris
updated,andwhentherequestedamountofentropyhasbeenobtained,theOKbut-
WhentheOKbuttonisclicked,thedialogisdestroyed,terminatingthemessage
loop.Theoutputfromthehashfunctioniscopiedintotheoutputbufferfromthe
Chapter11:Random Numbers
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from the Keyboard
|
637
}
if (dEntropy = cbOutput * 8) {
Chapter11:Random Numbers
11.21Gathering Entropy from Mouse Events on
Windows
Problem
Youneedentropyinalow-entropyenvironmentandcanprompttheusertomove
Solution
OnWindows,processallmouseevents.Mixintoanentropypoolthecurrentposi-
tionofthemousepointeronthescreen,alongwiththetimestampatwhicheach
eventwasprocessed.Estimateentropybaseduponyouroperatingenvironment;see
Therecanbeareasonableamountofentropyinmousemovement.Theentropy
comesnotjustfromwherethemousepointerisonthescreen,butfromwheneach
movementwasmade.Infact,themousepointerspositiononthescreencanhave
verylittleentropyinit,particularlyinanenvironmentwheretheremaybeverylittle
interactionfromalocaluser.Mostoftheentropywillcomefromtheexacttimingof
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from Mouse Events on Windows
|
639
numberofbitsofentropyhasbeencollected.Aprogressbarisalsodisplayedthat
Callthefunction
SpcGatherMouseEntropy()
tobegintheprocessofcollectingentropy.
Ithasthesamesignatureas
SpcGatherKeyboardEntropy()
fromRecipe11.20.This
Applicationinstancehandlenormallyobtainedfromthefirstargumentto
WinMain()
Handletothedialogsparentwindow.Itmaybespecifiedas
,inwhichcase
Numberofbytesofentropytoplaceintotheoutputbuffer.Theoutputbuffer
mustbesufficientlylargetoholdtherequestedamountofentropy.Thenumber
ofbytesofentropyrequestedshouldnotexceedthesizeofthehashfunction
used,whichisSHA1inthecodeprovided.SHA1producesa160-bitor20-byte
hash.Iftherequestedentropyissmallerthanthehashfunctionsoutput,the
SpcGatherMouseEntropy()
usestheCryptoAPItohashthedatacollectedfromthe
mouse.Itfirstacquiresacontextobject,thencreatesahashobject.Aftertheargu-
mentsarevalidated,thedialogresourceisloadedbycalling
DialogBoxParam()
,which
Chapter11:Random Numbers
createsamodaldialog.Amodaldialogcanbeusedforcapturingmousemessages
insteadofthemodelessdialogthatwasrequiredforgatheringkeyboardentropyin
Recipe11.20,becausenormaldialogprocessingdoesnteatmousemessagestheway
Oncethedialogissuccessfullycreated,themessagehandlingprocedurehandles
messages,whichwillbereceivedwheneverthemousepointermovesover
thedialogoritscontrols.Thepositionofthemousepointerisextractedfromthe
message,convertedtoscreencoordinates,combinedwithatimestamp,andfedinto
thehashobject.Ifthecurrentpointerpositionisthesameasthepreviouspointer
position,itisnotcountedasentropybutisaddedintothehashanyway.Asmouse
movementsarecollected,theprogressbarisupdated,andwhentherequested
WhentheOKbuttonisclicked,thedialogisdestroyed,terminatingthemessage
loop.Theoutputfromthehashfunctioniscopiedintotheoutputbufferfromthe
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from Mouse Events on Windows
|
641
Chapter11:Random Numbers
if (!(pbHashData = (BYTE *)LocalAlloc(LMEM_FIXED, cbHashData))) goto done;
DialogData.dEntropy = 0.0;
DialogData.cbRequested = cbOutput * 8;
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from Thread Timings
|
643
See Also
11.22Gathering Entropy from Thread Timings
Problem
Youwanttocollectsomeentropywithoutuserintervention,hopingthatthereis
Solution
Inpractice,timinghowlongittakestostartupandstopaparticularnumberof
threadscanprovideabitofentropy.Forexample,manyJavavirtualmachinesexclu-
Becausethethreadtimingdataisonlyindirectlyrelatedtoactualuserinput,itis
goodtobeextremelyconservativeaboutthequalityofthisentropysource.Werec-
Chapter11:Random Numbers
OnWindows,theideaisthesame,andthestructureofthecodeissimilar.Hereis
Copyright © 2003 OReilly & Associates, Inc. All rights reserved.
Gathering Entropy from System State
|
645
Westronglyrecommendthatyoudonotincreaseyourentropyesti-
matesbasedonanykernelstatecollected,particularlyonasystemthat
ismostlyidle.Muchofthetime,kernelstatechangesmoreslowly
thanpeoplethink.Inaddition,attackersmaybeabletoquerythe
Chapter11:Random Numbers
Often,thesecommandswillneedtorunwithsuperuserprivileges(forexample,
).Dependingonyourthreatmodel,suchcommandscanpossiblybemore