Some transformations need a source of randomness during execution. For this reason, we can insert statements that collect random values, preferably from variables that are input dependent.
We support two basic ways to collect entropy. You can insert statements within your program that collect values from (hopefully) input-dependent variables. Or, you can spin up a background thread that intermittently does so automatically. Regardless, the randomness we collect is of low quality, but good enough for our purposes.
At a minimum, you should issue the --Transform=InitEntropy
transformation,
since this creates the variables that hold the entropy.
You should issue as many --Transform=UpdateEntropy
as you
can, making sure you collect entropy from variables that are truly input dependent.
Option | Arguments | Description |
---|---|---|
--Transform | InitEntropy | Add initialization of the entropy variables. |
--InitEntropyKinds | thread, vars, * | Comma-separated list of the kinds of entropy generation to add. Default=thread,var.
|
--InitEntropyThreadName | string | The name of the generated background thread Default=entropyThread. |
--InitEntropyThreadSleep | INTSPEC | How long the background thread will sleep after having updated the entropy, in nanoseconds Default=1000. |
--InitEntropyTrace | update, use, check | Trace entropy values as they are generated during execution. This used to be a boolean, but from version 4.0, it can take on multiple values. Default=NONE.
|
--InitEntropyObfuscate | BOOLSPEC | Apply some light obfuscation on top of the entropy-generating expression. Default=FALSE. |
Option | Arguments | Description |
---|---|---|
--Transform | UpdateEntropy | Add updates to the entropy variables. |
--UpdateEntropyTrace | update, use, check | Trace entropy values as they are updated during execution. This used to be a boolean, but from version 4.0, it can take on multiple values. Default=NONE.
|
--UpdateEntropyObfuscate | BOOLSPEC | Apply some light obfuscation on top of the entropy-generating expression. Default=FALSE. |
--UpdateEntropyKinds | thread, vars, annotations, * | Comma-separated list of the kinds of entropy generation to add. Default=thread,var.
|
--UpdateEntropyVars | IDENTSPEC | Add to the entropy variables from these variables. Default=*. |
The command below initializes the entropy variables in main
,
and then collects randomness from variables x,y,z
in function inputData
, from variable packet
in function acceptNetworkPacket
, and from all variables
in function random
. It also spins up a background
thread from the tigress_init
function. The thread
function is called ENTROPYTHREAD, and it sleeps for
1000000 nanoseconds between updates.
tigress --Seed=0 --Verbosity=1 --Environment=... \
--Transform=InitEntropy \
--InitEntropyThreadName=ENTROPYTHREAD \
--InitEntropyThreadSleep=1000000\
--InitEntropyKinds=vars,thread \
--InitEntropyTrace=true \
--Transform=UpdateEntropy \
--Functions=inputData \
--UpdateEntropyKinds=vars \
--UpdateEntropyTrace=true \
--UpdateEntropyVars=x,y,z \
--Transform=UpdateEntropy \
--Functions=acceptNetworkPacket \
--UpdateEntropyKinds=vars \
--UpdateEntropyTrace=true \
--UpdateEntropyVars=packet \
--Transform=UpdateEntropy \
--Functions=random \
--UpdateEntropyKinds=vars \
--UpdateEntropyTrace=true \
--UpdateEntropyVars=p\* \
--Transform=UpdateEntropy \
--Functions=tigress_init \
--UpdateEntropyKinds=thread \
Instead of using --UpdateEntropyVars
you can use annotations in the source code to directly indicate which
variables should contribute to entropy calculation:
int foo (int x) {
...
ENTROPY_VARIABLE(x);
float f = x + 10;
ENTROPY_VARIABLE(f);
...
}
You should place these annotations in locations where the variable depends on input. Here's the Tigress command:
tigress ... \
--Transform=InitEntropy \
--Functions=main \
--InitEntropyKinds=annotations \
--Transform=UpdateEntropy \
--Functions=foo \
--UpdateEntropyKinds=annotations \
The idea of using threads and CPU performance counters to generate random numbers
was first introduced by Adrian Colesa, Radu Tudoran, and Sebastian Banescu in
Software Random Number Generation Based on Race Conditions.
Our implementation isn't as advanced at theirs since it only uses X86's rdtsc
counter. Unfortunately, other
counters are not available from user mode.