> >After that, you actually want to feed the entropy you're getting
> >from the radio tuner *into* /dev/[u]random.
>
> He may wish to pre-process the raw bits to remove any potential
> bias they may have.
>
> Here's what I do for random bits:
> http://www.etoan.com/random-number-generation/index.html

Nice!!! :) I wasn't aware such electronics is so cheap!

Here is the final version of the OTP generator:
Hints and constructive criticism welcomed.

News: Elementary sanity check on input data is performed.



//-- cut here ----------------- makernd.c ------------------ cut here ----
/*
## #######################################################################
##
## makernd - program for generation of random files suitable for one-time
## pads. Uses audio signal from soundcard input.
##
## Performs basic sanity check for sufficient entropy on the input.
## Reads 64 bytes from DSP, checks if there is at least one pair of
## adjanced bytes where the bytes are different by more than 16
## (arbitrarily chosen value). This should be replaced with some kind
## of statistical analysis. The check is also done on each block read
## from the input, discarding suspicious input data.
##
## Reads blocks of 128 bytes from RANDOMINPUT, hashes them with MD5,
## outputs 16-byte blocks to output file and RANDOMDEV (so as the side
## effect it feeds the entropy pool).
##
## Takes one mandatory parameter (number of random bytes to produce) and
## one optional parameter (output file name - uses stdout if not present).
##
## #######################################################################
*/

#include <stdio.h>
#include <stdlib.h>
#include <openssl/md5.h>

#define RANDOMDEV "/dev/urandom"
#define RANDOMINPUT "/dev/dsprandom"

char output[18];
FILE*fo,*frnd;

void outputbinary(char*s,long n)
{ while(n>0)
  {fprintf(fo,"%c",s[0] & 0xff);s++;n--;}
}

// FIXME: Replace with real statistical check
int isinsufficiententropy(char*data,int n)
{ int t;
  for(t=0;t<n-1;t++)if(abs((data[t+1]&0xff)-(data[t]&0xff))>16)return 0;
  return 1;
}

int checkinputentropy(FILE*f)
{ char data[64];
  fread(data,64,1,f);
  return isinsufficiententropy(data,64);
}

int output16bytes(FILE*f,long n)
{ char data[128];
  MD5_CTX c;
  MD5_Init(&c);
  MD5_Update(&c,output,16);
  for(;;){fread(data,128,1,f);
          if(!isinsufficiententropy(data,128))break;
          fprintf(stderr,"Insufficient input entropy. Rereading block.\n");}
  MD5_Update(&c,data,128);
  MD5_Final(output,&c);
  if(n>16)n=16;if(n<0)n=0;
  outputbinary(output,n);
  if(frnd)fwrite(output,16,1,frnd);
  return 0;
}

int main(int argc,char*argv[])
{
  FILE*f;
  long n;

  if(argc<2)
   {printf("makernd <LENGTH> [output.file]\n"
           "Creates LENGTH bytes of random numbers derived from "RANDOMINPUT", "
           "which should be a symlink to eg. /dev/dsp0 fed with analog signal "
           "from eg. a white noise generator.\n"
           "Outputs to stdout if output.file is not specified.\n"
           "Feeds the output also to "RANDOMDEV".\n");
    return 0;}

  n=atol(argv[1]);
  if(n<=0)
   {fprintf(stderr,"Argument '%s' has to be greater than zero.\n",argv[1]);
    return 111;}

  f=fopen(RANDOMINPUT,"r");
  if(!f)
   {perror("ERROR: Cannot open "RANDOMINPUT);
    fprintf(stderr,"Check if the symlink or device exists.\n");
    return 111;}

  if(checkinputentropy(f))
   {fprintf(stderr,"ERROR: Input entropy seems to be insufficient.\n"
                   "No two adjanced bytes in "RANDOMINPUT" that are different by more 
than 16.\n"
                   "Check the input signal volume.\n"
                   "Cowardly refusing to create any output.\n");
    return 1;}

  frnd=fopen(RANDOMDEV,"rw");
    if(frnd){fread(output,16,1,frnd);}
    else{fprintf(stderr,"Cannot open "RANDOMDEV", cannot initialize output. Proceeding 
anyway.\n");}

  if(argc>2){fo=fopen(argv[2],"w");
             if(!fo){perror("ERROR: Cannot open output file");return(111);}}
             else fo=stdout;

  while(n>0){output16bytes(f,n);n-=16;}

  fclose(f);fclose(frnd);
  return 0;
}

Reply via email to