Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 869681 Details for
Bug 982660
audio-entropyd doesn't work with or without pulseaudio
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch for audio-entropyd 2.0.3 with further enhancements
audio-entropyd-allow-32bit.patch (text/plain), 46.23 KB, created by
stan
on 2014-03-02 19:48:54 UTC
(
hide
)
Description:
Patch for audio-entropyd 2.0.3 with further enhancements
Filename:
MIME Type:
Creator:
stan
Created:
2014-03-02 19:48:54 UTC
Size:
46.23 KB
patch
obsolete
>--- audio-entropyd.c 2010-02-28 06:21:33.000000000 -0700 >+++ audio-entropyd.c 2014-03-02 11:31:02.991037473 -0700 >@@ -36,511 +36,865 @@ > #include "proc.h" > #include "val.h" > #include "RNGTEST.h" > #include "error.h" > >-#define RANDOM_DEVICE "/dev/random" >-#define DEFAULT_SAMPLE_RATE 11025 >-#define PID_FILE "/var/run/audio-entropyd.pid" >-#define DEFAULT_CLICK_READ (1 * DEFAULT_SAMPLE_RATE) >-#define DEFAULT_POOLSIZE_FN "/proc/sys/kernel/random/poolsize" >-#define RNGTEST_PENALTY (20000 / 8) /* how many bytes to skip when the rng-test fails */ >+#define RANDOM_DEVICE "/dev/random" >+#define DEFAULT_FRAME_RATE 22050 >+#define DEFAULT_SAMPLE_SIZE 11072 >+#define DEFAULT_SKIP_SIZE 11025 >+#define DEFAULT_CONFIGURATION_FILE "/etc/sysconfig/audio-entropyd" >+#define PID_FILE "/var/run/audio-entropyd.pid" >+#define DEFAULT_POOLSIZE_FN "/proc/sys/kernel/random/poolsize" >+#define RNGTEST_PENALTY (20000 / 8) /* how many bytes to skip when the rng-test fails */ > > void dolog(int level, char *format, ...); > >+/* Global Variables - they all have a leading capital case, and >+ * they are used throughout the program without passing. That's why >+ * the case is different, so they can be recognized. >+ * Not optimal as it can obscure the logic flow, but simple. */ > extern int loggingstate; >-int treshold = 0; >-char skip_test = 0; >-int error_state = 0; >-char dofork = 1; >-char *file = NULL; >- >-static char *cdevice = "hw:0"; /* capture device */ >-const char *id = "capture"; >-int err; >-int verbose=0; >-int format = -1; >+int Always_Close = 0; >+unsigned Frame_Rate = (unsigned) DEFAULT_FRAME_RATE; >+unsigned Process_Frames = (unsigned) DEFAULT_SAMPLE_SIZE; >+unsigned Skip_Frames = (unsigned) DEFAULT_SAMPLE_SIZE; >+char Internal_Test = 0; >+int Error_State = 0; >+int Entropy_Filter = 0; >+char Do_Fork = 1; >+char *Capture_File = NULL; >+static char *Capture_Device = "plughw:0"; /* capture device */ >+const char *Stream_Mode = "capture"; >+int Snd_Pcm_Err; >+int Verbose=0; >+int Snd_Pcm_Format = -1; > >-#define max(x, y) ((x)>(y)?(x):(y)) >+#define max(x, y) ((x)>(y)?(x):(y)) > > /* Prototypes */ >-void main_loop(const char *cdevice, int sample_rate); >-int setparams(snd_pcm_t *chandle, int sample_rate); >+void main_loop(void); >+int parse_options (int option_count, char **options); >+int read_config_file (FILE * infile, char ***config_options); >+void * Alloc (size_t len); >+char * StrnDup (char *str); >+char * StrMem (size_t slen); >+int setparams(snd_pcm_t *chandle); > void usage(void); > void credit_krng(int random_fd, struct rand_pool_info *entropy); > void daemonise(void); > void gracefully_exit(int signum); > void logging_handler(int signum); >-void get_random_data(int sample_rate, int skip_samples, int process_samples, int *n_output_bytes, char **output_buffer); >-int add_to_kernel_entropyspool(int handle, char *buffer, int nbytes); >+void get_random_data (snd_pcm_t *chandle, unsigned char *input_buffer, unsigned char *output_buffer, int *n_output_bytes); >+void add_entropy_bit (char bit, unsigned char *output_buffer, int *n_output_bytes); >+int add_to_kernel_entropyspool(int handle, unsigned char *buffer, int nbytes); > > /* Functions */ > > int main(int argc, char **argv) > { >- int sample_rate = DEFAULT_SAMPLE_RATE; >- int c; >- static struct option long_options[] = >- { >- {"device", 1, NULL, 'd' }, >- {"do-not-fork", 1, NULL, 'n' }, >- {"sample-rate", 1, NULL, 'N' }, >- {"skip-test", 0, NULL, 's' }, >- {"file", 1, NULL, 'f' }, >- {"verbose", 0, NULL, 'v' }, >- {"help", 0, NULL, 'h' }, >- {NULL, 0, NULL, 0 } >- }; >- >- /* Process commandline options */ >- while(1) >- { >- c = getopt_long (argc, argv, "f:nsr:d:N:vh", long_options, NULL); >- if (c == -1) >- break; >- >- switch(c) >- { >- case 'f': >- file = optarg; >- break; >- >- case 'n': >- dofork = 0; >- break; >- >- case 'N': >- sample_rate = atoi(optarg); >- break; >- >- case 'v': >- loggingstate = 1; >- verbose++; >- break; >- >- case 's': >- skip_test = 1; >- break; >- >- case 'd': >- cdevice = strdup(optarg); >- break; >- >- case 'h': >- usage(); >- exit(0); >- >- case '?': >- default: >- fprintf(stderr, "Invalid commandline options.\n\n"); >- usage(); >- exit(1); >- } >- } >- >- RNGTEST_init(); >- >- signal(SIGPIPE, SIG_IGN); >- signal(SIGHUP, gracefully_exit); >- signal(SIGINT, gracefully_exit); >- signal(SIGTERM, gracefully_exit); >- signal(SIGUSR1, logging_handler); >- signal(SIGUSR2, logging_handler); >- >- openlog("audio-entropyd", LOG_CONS, LOG_DAEMON); >- >- dolog(LOG_NOTICE, "audio-entropyd starting up"); >- >- if (mlockall(MCL_FUTURE | MCL_CURRENT) == -1) >- error_exit("mlockall failed"); >- >- if (dofork) >- daemonise(); >- >- main_loop(cdevice, sample_rate); >+ int option_count = 0, iii; >+ FILE *config_file; >+ char **config_file_options; >+ >+ config_file = fopen(DEFAULT_CONFIGURATION_FILE, "rt"); >+ if (!config_file) >+ error_exit("Couldn't open configuration file: %s", DEFAULT_CONFIGURATION_FILE); >+ option_count = read_config_file (config_file, &config_file_options); >+ fclose(config_file); >+ parse_options ( option_count, config_file_options); // Process configuration file >+ for (iii=0; iii < option_count; iii++) >+ { free (config_file_options [iii]); >+ } >+ free (config_file_options); >+ if (argc > 1) >+ { optind = 0; // start at first option >+ opterr = 0; // reset any error >+ optopt = 0; // reset any error >+ optarg = NULL; // reset any error >+ parse_options (argc, argv); // Process command line >+ } >+ RNGTEST_init(); >+ signal(SIGPIPE, SIG_IGN); >+ signal(SIGHUP, gracefully_exit); >+ signal(SIGINT, gracefully_exit); >+ signal(SIGTERM, gracefully_exit); >+ signal(SIGUSR1, logging_handler); >+ signal(SIGUSR2, logging_handler); >+ openlog("audio-entropyd", LOG_CONS, LOG_DAEMON); >+ dolog(LOG_NOTICE, "audio-entropyd starting up"); >+ if (mlockall(MCL_FUTURE | MCL_CURRENT) == -1) >+ error_exit("mlockall failed"); >+ if (Do_Fork) >+ daemonise(); >+ main_loop(); >+ exit(0); >+} > >- exit(0); >+/* >+ Parse the options passed in the char** array. >+ lines and comments. Rets: 0 on success. >+*/ >+int >+parse_options (int option_count, char **options) >+{ int c; >+ static struct option long_options[] = >+ { >+ {"always_close", 0, NULL, 'a' }, >+ {"device", 1, NULL, 'd' }, >+ {"do-not-fork", 0, NULL, 'n' }, >+ {"entropy-filter", 1, NULL, 'e' }, >+ {"sample-rate", 1, NULL, 'r' }, >+ {"sample-size", 1, NULL, 'z' }, >+ {"skip-size", 1, NULL, 's' }, >+ {"internal-test", 0, NULL, 'i' }, >+ {"store-in-file", 1, NULL, 'f' }, >+ {"verbose", 0, NULL, 'v' }, >+ {"help", 0, NULL, 'h' }, >+ {NULL, 0, NULL, 0 } >+ }; >+ >+ while(1) >+ { c = getopt_long (option_count, options, "ad:e:f:hinr:s:vz:", long_options, NULL); >+ if (c == -1) >+ break; >+ switch(c) >+ { case 'f': >+ Capture_File = StrnDup (optarg); >+ break; >+ case 'a': >+ Always_Close = 1; >+ break; >+ case 'n': >+ Do_Fork = 0; >+ break; >+ case 'r': >+ Frame_Rate = (unsigned) atoi(optarg); >+ break; >+ case 'z': >+ Process_Frames = (unsigned) atoi(optarg); >+ break; >+ case 's': >+ Skip_Frames = (unsigned) atoi(optarg); >+ break; >+ case 'v': >+ loggingstate = 1; >+ Verbose++; >+ break; >+ case 'i': >+ Internal_Test = 1; >+ break; >+ case 'e': >+ Entropy_Filter = atoi(optarg); >+ break; >+ case 'd': >+ Capture_Device = StrnDup(optarg); >+ break; >+ case 'h': >+ usage(); >+ exit(0); >+ case '?': >+ default: >+ fprintf(stderr, "Invalid commandline options.\n\n"); >+ usage(); >+ exit(1); >+ break; >+ } >+ } >+ return 0; > } > >-int setparams(snd_pcm_t *chandle, int sample_rate) >+/* >+ Read a configuration file, discarding blank >+ lines and comments. Rets: option count on success. >+ Everything from the file is put into an argv like array. >+*/ >+ >+int >+read_config_file (FILE * infile, char ***config_options) > { >- snd_pcm_hw_params_t *ct_params; /* templates with rate, format and channels */ >- snd_pcm_hw_params_alloca(&ct_params); >+ char *curr_option, *retptr, *workline, *cmnt, *token; >+ char **all_options; >+ int iii, line_count = 0, configuration_count = 0; >+ >+ workline= StrMem (256); >+ curr_option = StrnDup ("audio_entropyd"); // save the program name to simulate argv >+ all_options = (char **) StrMem ((sizeof (char *)) * (configuration_count+1)); // allocate an array for option char pointers, including the new option >+ configuration_count++; // update the option count >+ *(all_options + configuration_count - 1) = curr_option; // append the new option pointer >+ *config_options = all_options; // point to the new option pointer array >+ retptr = fgets (workline, 256, infile); >+ if (retptr == NULL) >+ error_exit ("Unable to read line from configuration file"); >+ while (*workline != '\0') >+ { line_count++; >+ token = strtok (workline, " \t\n"); // get first token separated by spaces, tabs, or newline >+ if (token) // not an empty line >+ { cmnt = strchr (workline, '#'); >+ if (token[0] == '-') // options line >+ { if (cmnt) >+ strncpy (cmnt, "\0", 1); // truncate at comment >+ curr_option = StrnDup (workline); // duplicate the option >+ all_options = (char **) StrMem ((sizeof (char *)) * (configuration_count+1)); // allocate an array for option char pointers, including the new option >+ for (iii = 0; iii < configuration_count; iii++) // transfer existing pointers to the new array of option pointers >+ { *(all_options + iii) = *((*config_options) + iii); >+ } >+ configuration_count++; // update the option count >+ *(all_options + configuration_count - 1) = curr_option; // append the new option pointer >+ free (*config_options); // free the existing option pointer array >+ *config_options = all_options; // point to the new option pointer array >+ } >+ else if (token[0] == '#') // line is a comment >+ ; // do nothing >+ else >+ { if (Verbose > 1) >+ dolog(LOG_DEBUG, "Skipped line %d in configuration file with invalid %s at start of line", line_count, token); >+ } >+ } >+ memset (workline, 0x00, 256); >+ retptr = fgets (workline, 256, infile); >+ } >+ curr_option = NULL; // terminate like argv is terminated, with a null char*. >+ all_options = (char **) StrMem ((sizeof (char *)) * (configuration_count+1)); // allocate an array for option char pointers, including the new option >+ for (iii = 0; iii < configuration_count; iii++) // transfer existing pointers to the new array of option pointers >+ { *(all_options + iii) = *((*config_options) + iii); >+ } >+ *(all_options + configuration_count) = curr_option; >+ free (*config_options); // free the existing option pointer array >+ //config_options = &all_options; // point to the new option pointer array >+ *config_options = all_options; // point to the new option pointer array >+ if (*workline == '\0') >+ { if (feof (infile)) >+ { free (workline); >+ return configuration_count; >+ } >+ free (workline); >+ error_exit ("Read error on configuration file"); >+ } >+ free (workline); >+ return configuration_count; >+} > >- err = snd_pcm_hw_params_any(chandle, ct_params); >- if (err < 0) >- error_exit("Broken configuration for %s PCM: no configurations available: %s", id, snd_strerror(err)); >- >- /* Disable rate resampling */ >- err = snd_pcm_hw_params_set_rate_resample(chandle, ct_params, 0); >- if (err < 0) >- error_exit("Could not disable rate resampling: %s", snd_strerror(err)); >- >- /* Set access to SND_PCM_ACCESS_RW_INTERLEAVED */ >- err = snd_pcm_hw_params_set_access(chandle, ct_params, SND_PCM_ACCESS_RW_INTERLEAVED); >- if (err < 0) >- error_exit("Could not set access to SND_PCM_ACCESS_RW_INTERLEAVED: %s", snd_strerror(err)); >- >- /* Restrict a configuration space to have rate nearest to our target rate */ >- err = snd_pcm_hw_params_set_rate_near(chandle, ct_params, &sample_rate, 0); >- if (err < 0) >- error_exit("Rate %iHz not available for %s: %s", sample_rate, id, snd_strerror(err)); >- >- /* Set sample format */ >- format = SND_PCM_FORMAT_S16_BE; >- err = snd_pcm_hw_params_set_format(chandle, ct_params, format); >- if (err < 0) >- { >- format = SND_PCM_FORMAT_S16_LE; >- err = snd_pcm_hw_params_set_format(chandle, ct_params, format); >- } >- if (err < 0) >- error_exit("Sample format (SND_PCM_FORMAT_S16_BE and _LE) not available for %s: %s", id, snd_strerror(err)); >- >- /* Set stereo */ >- err = snd_pcm_hw_params_set_channels(chandle, ct_params, 2); >- if (err < 0) >- error_exit("Channels count (%i) not available for %s: %s", 2, id, snd_strerror(err)); >- >- /* Apply settings to sound device */ >- err = snd_pcm_hw_params(chandle, ct_params); >- if (err < 0) >- error_exit("Could not apply settings to sound device!"); >+void * >+Alloc (size_t len) >+{ void *p = calloc (1, len); >+ if (!p) >+ error_exit ("Out of memory in request for %u", len); >+ return p; >+} > >- return 0; >+char * >+StrnDup (char *str) >+{ size_t len = strlen (str); >+ char *rv = strndup (str, len); >+ if (!rv) >+ error_exit ("Out of memory in StrnDup"); >+ return rv; > } > >-void main_loop(const char *cdevice, int sample_rate) >-{ >- unsigned char *output_buffer = NULL; >- int n_output_bytes = -1; >- int random_fd = -1, max_bits; >- FILE *poolsize_fh; >- >- /* Open kernel random device */ >- random_fd = open(RANDOM_DEVICE, O_RDWR); >- if (random_fd == -1) >- error_exit("Couldn't open random device: %m"); >- >- /* find out poolsize */ >- poolsize_fh = fopen(DEFAULT_POOLSIZE_FN, "rb"); >- if (!poolsize_fh) >- error_exit("Couldn't open poolsize file: %m"); >- fscanf(poolsize_fh, "%d", &max_bits); >- fclose(poolsize_fh); >- >- /* first get some data so that we can immediately submit something when the >- * kernel entropy-buffer gets below some limit >- */ >- get_random_data(sample_rate, DEFAULT_CLICK_READ, DEFAULT_SAMPLE_RATE, &n_output_bytes, &output_buffer); >- >- /* Main read loop */ >- for(;;) >- { >- int added = 0, before, loop, after; >- fd_set write_fd; >- FD_ZERO(&write_fd); >- FD_SET(random_fd, &write_fd); >- >- if (!file) >- { >- for(;;) >- { >- int rc = select(random_fd+1, NULL, &write_fd, NULL, NULL); /* wait for krng */ >- if (rc >= 0) break; >- if (errno != EINTR) >- error_exit("Select error: %m"); >- } >- } >- >- /* find out how many bits to add */ >- if (ioctl(random_fd, RNDGETENTCNT, &before) == -1) >- error_exit("Couldn't query entropy-level from kernel"); >- >- dolog(LOG_DEBUG, "woke up due to low entropy state (%d bits left)", before); >- >- /* loop until the buffer is (supposed to be) full: we do NOT check the number of bits >- * currently in the buffer each iteration, since (on a heavily used random-driver) >- * audio-entropyd might run constantly, using a lot of cpu-usage >- */ >- if (verbose > 1) >- printf("max_bits: %d\n", max_bits); >- for(loop=0; loop < max_bits;) >- { >- if (verbose > 1) >- dolog(LOG_DEBUG, "n_output_bytes: %d", n_output_bytes); >- >- if (n_output_bytes > 0) >- { >- int cur_added; >- >- if (file) >- { >- FILE *fh = fopen(file, "a+"); >- if (!fh) >- error_exit("error accessing file %s", file); >- >- if (fwrite(output_buffer, 1, n_output_bytes, fh) != n_output_bytes) >- error_exit("error writeing to file"); >- >- fclose(fh); >- >- cur_added = n_output_bytes * 8; >- } >- else >- { >- cur_added = add_to_kernel_entropyspool(random_fd, output_buffer, n_output_bytes); >- } >- >- added += cur_added; >- loop += cur_added; >- >- if (verbose > 1) >- dolog(LOG_DEBUG, "%d bits of data, %d bits usable were added, total %d added", n_output_bytes * 8, cur_added, added); >- } >- >- /* Get number of bits in KRNG after credit */ >- if (ioctl(random_fd, RNDGETENTCNT, &after) == -1) >- error_exit("Coundn't query entropy-level from kernel: %m"); >- >- if (verbose > 1 && after < max_bits) >- dolog(LOG_DEBUG, "minimum level not reached: %d", after); >- >- free(output_buffer); >- output_buffer = NULL; >- get_random_data(sample_rate, DEFAULT_CLICK_READ, DEFAULT_SAMPLE_RATE, &n_output_bytes, &output_buffer); >- } >+/* Allocate a string of the passed in size from memory. >+ * Strings allocated with this routine can use the StrCat >+ * routine below safely. Does *not* allocate an extra >+ * position for the NULL terminator. Callers responsibility. */ >+char * >+StrMem (size_t slen) >+{ char *nstr = NULL; >+ nstr = (char *) Alloc (slen); >+ if (!nstr) >+ error_exit ("Out of memory in StrMem"); >+ return nstr; >+} >+ >+int setparams(snd_pcm_t *chandle) >+{ >+ snd_pcm_hw_params_t *ct_params; /* templates with rate, format and channels */ >+ snd_pcm_hw_params_alloca(&ct_params); >+ >+ Snd_Pcm_Err = snd_pcm_hw_params_any(chandle, ct_params); >+ if (Snd_Pcm_Err < 0) >+ error_exit("Broken configuration for %s PCM: no configurations available: %s", Stream_Mode, snd_strerror(Snd_Pcm_Err)); >+ >+ /* Disable rate resampling */ >+ // redundant with set_rate_near, as set_rate_near always picks a native rate of the device that would not be resampled. >+ //Snd_Pcm_Err = snd_pcm_hw_params_set_rate_resample(chandle, ct_params, 0); >+ //if (Snd_Pcm_Err < 0) >+ // error_exit("Could not disable rate resampling: %s", snd_strerror(Snd_Pcm_Err)); >+ >+ /* Set access to SND_PCM_ACCESS_RW_INTERLEAVED */ >+ Snd_Pcm_Err = snd_pcm_hw_params_set_access(chandle, ct_params, SND_PCM_ACCESS_RW_INTERLEAVED); >+ if (Snd_Pcm_Err < 0) >+ error_exit("Could not set access to SND_PCM_ACCESS_RW_INTERLEAVED: %s", snd_strerror(Snd_Pcm_Err)); >+ >+ /* Restrict a configuration space to have rate nearest to our target rate */ >+ Snd_Pcm_Err = snd_pcm_hw_params_set_rate_near(chandle, ct_params, &Frame_Rate, 0); >+ if (Snd_Pcm_Err < 0) >+ error_exit("Rate %iHz not available for %s: %s", Frame_Rate, Stream_Mode, snd_strerror(Snd_Pcm_Err)); >+ >+ /* Set sample format appropriate for architecture */ >+ int test_int = 1; >+ if ((* (char *) &test_int) == 1) >+ { Snd_Pcm_Format = SND_PCM_FORMAT_S32_LE; >+ Snd_Pcm_Err = snd_pcm_hw_params_set_format(chandle, ct_params, Snd_Pcm_Format); >+ if (Snd_Pcm_Err < 0) >+ { error_exit("Sample format SND_PCM_FORMAT_S32_LE not available for %s: %s", Stream_Mode, snd_strerror(Snd_Pcm_Err)); >+ } >+ } >+ else >+ { Snd_Pcm_Format = SND_PCM_FORMAT_S32_BE; >+ Snd_Pcm_Err = snd_pcm_hw_params_set_format(chandle, ct_params, Snd_Pcm_Format); >+ if (Snd_Pcm_Err < 0) >+ { error_exit("Sample format SND_PCM_FORMAT_S32_BE not available for %s: %s", Stream_Mode, snd_strerror(Snd_Pcm_Err)); >+ } >+ } >+ >+ /* Set stereo */ >+ Snd_Pcm_Err = snd_pcm_hw_params_set_channels(chandle, ct_params, 2); >+ if (Snd_Pcm_Err < 0) >+ error_exit("Channels count (%i) not available for %s: %s", 2, Stream_Mode, snd_strerror(Snd_Pcm_Err)); >+ >+ /* Apply settings to sound device */ >+ Snd_Pcm_Err = snd_pcm_hw_params(chandle, ct_params); >+ if (Snd_Pcm_Err < 0) >+ error_exit("Could not apply settings to sound device!"); >+ >+ int can_pause = snd_pcm_hw_params_can_pause (ct_params); >+ int can_resume = snd_pcm_hw_params_can_resume (ct_params); >+ if (can_pause == 1 && can_resume == 1) >+ return 1; >+ else >+ return 0; >+} > >- dolog(LOG_INFO, "Entropy credit of %i bits made (%i bits before, %i bits after)", added, before, after); >- } >+void main_loop(void) >+{ unsigned input_buffer_size, output_buffer_size; >+ unsigned char *input_buffer = NULL; >+ unsigned char *output_buffer = NULL; >+ int can_pause_resume = 0, pause = 1, resume = 0; >+ int n_output_bytes = -1; >+ int random_fd = -1, max_bits; >+ FILE *poolsize_fh; >+ snd_pcm_t *chandle = NULL; >+ >+ if ((Snd_Pcm_Err = snd_pcm_open(&chandle, Capture_Device, SND_PCM_STREAM_CAPTURE, 0)) < 0) >+ error_exit("Record open error: %s", snd_strerror(Snd_Pcm_Err)); >+ >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "main loop chandle %p", chandle); >+ >+ /* Open and set up ALSA device for reading */ >+ can_pause_resume = setparams(chandle); >+ >+ input_buffer_size = snd_pcm_frames_to_bytes(chandle, Frame_Rate); >+ input_buffer = (unsigned char *)malloc(input_buffer_size); >+ output_buffer_size = (Process_Frames / 8) + (8 - ((Process_Frames / 8) % 8)); // max of 1 bit of entropy per frame >+ output_buffer = (unsigned char *)malloc(output_buffer_size); >+ if (!input_buffer || !output_buffer) >+ error_exit("problem allocating %d bytes of memory", input_buffer_size); >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "Input buffer size: %d bytes", input_buffer_size); >+ >+ /* Discard the first data read */ >+ /* it often contains weird looking data - probably a click from */ >+ /* driver loading / card initialisation */ >+ /* Read a buffer of audio */ >+ int total = Skip_Frames; >+ int n_to_do = Process_Frames; >+ if (Skip_Frames < Process_Frames) >+ n_to_do = Skip_Frames; >+ unsigned char *dummy = input_buffer; >+ while (total > 0) >+ { while (n_to_do > 0) >+ { snd_pcm_sframes_t frames_read = snd_pcm_readi(chandle, dummy, Process_Frames); >+ /* Make sure we aren't hitting a disconnect/suspend case */ >+ if (frames_read < 0) >+ snd_pcm_recover(chandle, frames_read, 0); >+ /* Nope, something else is wrong. Bail. */ >+ if (frames_read < 0) >+ { snd_pcm_close(chandle); >+ free(input_buffer); >+ free(output_buffer); >+ error_exit("Read initial throw away data error: %m"); >+ } >+ else >+ { n_to_do -= frames_read; >+ total -= frames_read; >+ dummy += frames_read; >+ } >+ } >+ n_to_do = Process_Frames; >+ dummy = input_buffer; >+ } >+ /* Open kernel random device */ >+ random_fd = open(RANDOM_DEVICE, O_RDWR); >+ if (random_fd == -1) >+ error_exit("Couldn't open random device: %m"); >+ >+ /* find out poolsize */ >+ poolsize_fh = fopen(DEFAULT_POOLSIZE_FN, "rb"); >+ if (!poolsize_fh) >+ error_exit("Couldn't open poolsize file: %m"); >+ fscanf(poolsize_fh, "%d", &max_bits); >+ fclose(poolsize_fh); >+ /* first get some data so that we can immediately submit something when the >+ * kernel entropy-buffer gets below some limit >+ */ >+ get_random_data(chandle, input_buffer, output_buffer, &n_output_bytes); >+ if (can_pause_resume && Always_Close == 0) >+ snd_pcm_pause (chandle, pause); >+ else >+ snd_pcm_close(chandle); >+ /* Main read loop */ >+ for(;;) >+ { int added = 0, before, loop, after; >+ fd_set write_fd; >+ FD_ZERO(&write_fd); >+ FD_SET(random_fd, &write_fd); >+ if (!Capture_File) >+ { for(;;) >+ { int rc = select(random_fd+1, NULL, &write_fd, NULL, NULL); /* wait for krng */ >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "select return code rc %d", rc); >+ if (rc >= 0) >+ break; >+ else if (errno != EINTR) >+ error_exit("Select error: %m"); >+ } >+ } >+ /* find out how many bits to add */ >+ if (ioctl(random_fd, RNDGETENTCNT, &before) == -1) >+ error_exit("Couldn't query entropy-level from kernel"); >+ dolog(LOG_DEBUG, "woke up due to low entropy state (%d bits left)", before); >+ /* loop until the buffer is (supposed to be) full: we do NOT check the number of bits >+ * currently in the buffer each iteration, since (on a heavily used random-driver) >+ * audio-entropyd might run constantly, using a lot of cpu-usage >+ */ >+ if (Verbose > 1) >+ printf("max_bits: %d\n", max_bits); >+ if (can_pause_resume && Always_Close == 0) >+ snd_pcm_pause (chandle, resume); >+ else // no pause resume on this device, have to re initialize each time to avoid overrun errors >+ { if ((Snd_Pcm_Err = snd_pcm_open(&chandle, Capture_Device, SND_PCM_STREAM_CAPTURE, 0)) < 0) >+ error_exit("Record open error: %s", snd_strerror(Snd_Pcm_Err)); >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "main loop chandle %p", chandle); >+ /* Open and set up ALSA device for reading */ >+ setparams(chandle); >+ /* Discard the first data read */ >+ /* it often contains weird looking data - probably a click from */ >+ /* driver loading / card initialisation */ >+ /* Read a buffer of audio */ >+ int total = Skip_Frames; >+ int n_to_do = Process_Frames; >+ if (Skip_Frames < Process_Frames) >+ n_to_do = Skip_Frames; >+ unsigned char *dummy = input_buffer; >+ while (total > 0) >+ { while (n_to_do > 0) >+ { snd_pcm_sframes_t frames_read = snd_pcm_readi(chandle, dummy, Process_Frames); >+ /* Make sure we aren't hitting a disconnect/suspend case */ >+ if (frames_read < 0) >+ snd_pcm_recover(chandle, frames_read, 0); >+ /* Nope, something else is wrong. Bail. */ >+ if (frames_read < 0) >+ { snd_pcm_close(chandle); >+ free(input_buffer); >+ free(output_buffer); >+ error_exit("Read initial throw away data error: %m"); >+ } >+ else >+ { n_to_do -= frames_read; >+ total -= frames_read; >+ dummy += frames_read; >+ } >+ } >+ n_to_do = Process_Frames; >+ dummy = input_buffer; >+ } >+ } >+ for(loop=0; loop < max_bits;) >+ { if (Verbose > 1) >+ dolog(LOG_DEBUG, "n_output_bytes: %d", n_output_bytes); >+ if (n_output_bytes > 0) >+ { int cur_added; >+ if (Capture_File) >+ { FILE *fh = fopen(Capture_File, "a+"); >+ if (!fh) >+ error_exit("error accessing Capture_File %s", Capture_File); >+ if (fwrite(output_buffer, 1, n_output_bytes, fh) != n_output_bytes) >+ error_exit("error writeing to Capture_File"); >+ fclose(fh); >+ cur_added = n_output_bytes * 8; >+ } >+ else >+ cur_added = add_to_kernel_entropyspool(random_fd, output_buffer, n_output_bytes); >+ added += cur_added; >+ loop += cur_added; >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "%d bits of data, %d bits usable were added, total %d added", n_output_bytes * 8, cur_added, added); >+ } >+ /* Get number of bits in KRNG after credit */ >+ if (ioctl(random_fd, RNDGETENTCNT, &after) == -1) >+ error_exit("Coundn't query entropy-level from kernel: %m"); >+ if (Verbose > 1 && after < max_bits) >+ dolog(LOG_DEBUG, "minimum level not reached: %d", after); >+ memset (output_buffer, 0x00, output_buffer_size); >+ get_random_data(chandle, input_buffer, output_buffer, &n_output_bytes); >+ } >+ dolog(LOG_INFO, "Entropy credit of %i bits made (%i bits before, %i bits after)", added, before, after); >+ if (can_pause_resume && Always_Close == 0) >+ snd_pcm_pause (chandle, pause); >+ else >+ snd_pcm_close(chandle); >+ } >+ if (can_pause_resume && Always_Close == 0) >+ snd_pcm_close(chandle); >+ free(input_buffer); >+ free(output_buffer); > } > >-int add_to_kernel_entropyspool(int handle, char *buffer, int nbytes) >+int add_to_kernel_entropyspool(int handle, unsigned char *buffer, int nbytes) > { >- double nbits; >- struct rand_pool_info *output; >+ double nbits; >+ struct rand_pool_info *output; > >- output = (struct rand_pool_info *)malloc(sizeof(struct rand_pool_info) + nbytes); >- if (!output) >- error_exit("malloc failure in add_to_kernel_entropyspool"); >- >- // calculate number of bits in the block of >- // data. put in structure >- nbits = calc_nbits_in_data((unsigned char *)buffer, nbytes); >- if (nbits >= 1.0) >- { >- output -> entropy_count = (int)nbits; >- output -> buf_size = nbytes; >- memcpy(output -> buf, buffer, nbytes); >- >- if (ioctl(handle, RNDADDENTROPY, output) == -1) >- error_exit("RNDADDENTROPY failed!"); >- } >+ output = (struct rand_pool_info *)malloc(sizeof(struct rand_pool_info) + nbytes); >+ if (!output) >+ error_exit("malloc failure in add_to_kernel_entropyspool"); >+ >+ // calculate number of bits in the block of >+ // data. put in structure >+ nbits = calc_nbits_in_data((unsigned char *)buffer, nbytes); >+ if (nbits >= 1.0) >+ { >+ output -> entropy_count = (int)nbits; >+ output -> buf_size = nbytes; >+ memcpy(output -> buf, buffer, nbytes); >+ >+ if (ioctl(handle, RNDADDENTROPY, output) == -1) >+ error_exit("RNDADDENTROPY failed!"); >+ } > >- free(output); >+ free(output); > >- return (int)nbits; >+ return (int)nbits; > } > > #define order(a, b) (((a) == (b)) ? -1 : (((a) > (b)) ? 1 : 0)) > >-void get_random_data(int sample_rate, int skip_samples, int process_samples, int *n_output_bytes, char **output_buffer) >+void get_random_data (snd_pcm_t *chandle, unsigned char *input_buffer, unsigned char *output_buffer, int *n_output_bytes) > { >- int n_to_do, bits_out=0, loop; >- char *dummy; >- static short psl=0, psr=0; /* previous samples */ >+ int n_to_do, bits_out=0, loop; >+ unsigned char *dummy; >+ unsigned char byte_out=0; >+ static int psl=0, psr=0; /* previous samples */ > static char a=1; /* alternater */ >- unsigned char byte_out=0; >- int input_buffer_size; >- char *input_buffer; >- snd_pcm_t *chandle; >- >- if (verbose > 1) >- dolog(LOG_DEBUG, "get_random_data(%p, %d, %d, %p, %p)", chandle, skip_samples, process_samples, n_output_bytes, output_buffer); >- >- if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE, 0)) < 0) >- error_exit("Record open error: %s", snd_strerror(err)); >- >- /* Open and set up ALSA device for reading */ >- setparams(chandle, sample_rate); >- >- *n_output_bytes=0; >- >- input_buffer_size = snd_pcm_frames_to_bytes(chandle, max(skip_samples, process_samples)) * 2; /* *2: stereo! */ >- input_buffer = (char *)malloc(input_buffer_size); >- *output_buffer = (char *)malloc(input_buffer_size); >- if (!input_buffer || !output_buffer) >- error_exit("problem allocating %d bytes of memory", input_buffer_size); >- if (verbose > 1) >- dolog(LOG_DEBUG, "Input buffer size: %d bytes", input_buffer_size); >- >- /* Discard the first data read */ >- /* it often contains weird looking data - probably a click from */ >- /* driver loading / card initialisation */ >- snd_pcm_sframes_t garbage_frames_read = snd_pcm_readi(chandle, input_buffer, skip_samples); >- /* Make sure we aren't hitting a disconnect/suspend case */ >- if (garbage_frames_read < 0) >- snd_pcm_recover(chandle, garbage_frames_read, 0); >- /* Nope, something else is wrong. Bail. */ >- if (garbage_frames_read < 0) >- error_exit("Get random data: read error: %m"); >- >- /* Read a buffer of audio */ >- n_to_do = process_samples * 2; >- dummy = input_buffer; >- while (n_to_do > 0) >- { >- snd_pcm_sframes_t frames_read = snd_pcm_readi(chandle, dummy, n_to_do); >- /* Make sure we aren't hitting a disconnect/suspend case */ >- if (frames_read < 0) >- frames_read = snd_pcm_recover(chandle, frames_read, 0); >- /* Nope, something else is wrong. Bail. */ >- if (frames_read < 0) >- error_exit("Read error: %m"); >- if (frames_read == -1) >- { >- if (errno != EINTR) >- error_exit("Read error: %m"); >- } >- else >- { >- n_to_do -= frames_read; >- dummy += frames_read; >- } >- } >- snd_pcm_close(chandle); >- >- /* de-biase the data */ >- for(loop=0; loop<(process_samples * 2/*16bits*/ * 2/*stereo*/ * 2); loop+=8) >- { >- int w1, w2, w3, w4, o1, o2; >- >- if (format == SND_PCM_FORMAT_S16_BE) >- { >- w1 = (input_buffer[loop+0]<<8) + input_buffer[loop+1]; >- w2 = (input_buffer[loop+2]<<8) + input_buffer[loop+3]; >- w3 = (input_buffer[loop+4]<<8) + input_buffer[loop+5]; >- w4 = (input_buffer[loop+6]<<8) + input_buffer[loop+7]; >- } >- else >- { >- w1 = (input_buffer[loop+1]<<8) + input_buffer[loop+0]; >- w2 = (input_buffer[loop+3]<<8) + input_buffer[loop+2]; >- w3 = (input_buffer[loop+5]<<8) + input_buffer[loop+4]; >- w4 = (input_buffer[loop+7]<<8) + input_buffer[loop+6]; >- } >- >- /* Determine order of channels for each sample, subtract previous sample >- * to compensate for unbalanced audio devices */ >- o1 = order(w1-psl, w2-psr); >- o2 = order(w3-psl, w4-psr); >- if (a > 0) >- { >- psl = w3; >- psr = w4; >- } >- else >- { >- psl = w1; >- psr = w2; >- } >- >- /* If both samples have the same order, there is bias in the samples, so we >- * discard them; if both channels are equal on either sample, we discard >- * them too; additionally, alternate the sample we'll use next (even more >- * bias removal) */ >- if (o1 == o2 || o1 < 0 || o2 < 0) >- { >- a = -a; >- } >- else >- { >- /* We've got a random bit; the bit is either the order from the first or >- * the second sample, determined by the alternator 'a' */ >- char bit = (a > 0) ? o1 : o2; >- >- byte_out <<= 1; >- byte_out += bit; >- >- bits_out++; >- >- if (bits_out>=8) >- { >- if (error_state == 0 || skip_test == 0) >- { >- (*output_buffer)[*n_output_bytes]=byte_out; >- (*n_output_bytes)++; >- } >- bits_out=0; >- >- RNGTEST_add(byte_out); >- if (skip_test == 0 && RNGTEST() == -1) >- { >- if (error_state == 0) >- dolog(LOG_CRIT, "test of random data failed, skipping %d bytes before re-using data-stream (%d bytes in flush)", RNGTEST_PENALTY, error_state); >- error_state = RNGTEST_PENALTY; >- *n_output_bytes = 0; >- } >- else >- { >- if (error_state > 0) >- { >- error_state--; >- >- if (error_state == 0) >- dolog(LOG_INFO, "Restarting fetching of entropy data"); >- } >- } >- } >- } >- } >+ char o1, o2; >+ int min_left_val = 0x0fffffff, max_left_val = 0, min_right_val = 0x0fffffff, max_right_val = 0; >+ long left_input_total = 0, right_input_total = 0; >+ float dc_offset_left = 0.0, dc_offset_right = 0.0; >+ int left_processed_samples [Process_Frames], right_processed_samples [Process_Frames]; >+ >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "get_random_data(%p, %u, %d, %d, %p, %p)", chandle, Frame_Rate, Process_Frames, input_buffer, output_buffer, n_output_bytes); >+ *n_output_bytes=0; >+ /* Read a buffer of audio */ >+ n_to_do = Process_Frames; >+ dummy = input_buffer; >+ while (n_to_do > 0) >+ { snd_pcm_sframes_t frames_read = snd_pcm_readi(chandle, dummy, n_to_do); >+ /* Make sure we aren't hitting a disconnect/suspend case */ >+ if (frames_read < 0) >+ frames_read = snd_pcm_recover(chandle, frames_read, 0); >+ /* Nope, something else is wrong. Bail. */ >+ if (frames_read < 0) >+ error_exit("Read error: %m"); >+ if (frames_read == -1) >+ { if (errno != EINTR) >+ error_exit("Read error: %m"); >+ } else >+ { n_to_do -= frames_read; >+ dummy += frames_read; >+ if (n_to_do > 0) >+ { double time_for_frames = (double) n_to_do / (double) Frame_Rate; // how long to create that many frames? >+ long nanoseconds = floor ((time_for_frames * 1000000.)); // how many nanoseconds is that? >+ struct timespec time_to_wait, time_left; >+ time_to_wait.tv_sec = (long) floor (time_for_frames); >+ time_to_wait.tv_nsec = (nanoseconds % 1000000); >+ int wait_retval = nanosleep (&time_to_wait, &time_left); // wait for that many nanoseconds >+ } >+ } >+ } >+ int iii = 0; >+ /* de-bias the data */ >+ for (loop = 0; loop < (Process_Frames*2); loop += 2) >+ { int32_t w1, w2; >+ /* because we are using plughw, alsa (or pulse) will have formatted the data >+ * to be signed 32 as requested by shifting, regardless of device internal format. >+ * 32 bits should take care of >+ * sound cards for now as there is really no discernable difference above that >+ * for human ears, while it allows for extracting maximum entropy from cards >+ * with larger internal formats. I think the new hd-intel standard defaults to >+ * 32 bit. Most systems will have this onboard now. >+ * Note that big endian or little endian doesn't matter as we are reading in native >+ * format, whatever it is for int32_t. >+ */ >+ w1 = ((int32_t *) input_buffer) [loop + 0]; >+ left_processed_samples [iii] = w1; >+ left_input_total += w1; >+ if (w1 < min_left_val) >+ { min_left_val = w1; >+ } else if (w1 > max_left_val) >+ max_left_val = w1; >+ w2 = ((int32_t *) input_buffer) [loop + 1]; >+ right_processed_samples [iii] = w2; >+ right_input_total += w2; >+ if (w2 < min_right_val) >+ { min_right_val = w2; >+ } else if (w2 > max_right_val) >+ max_right_val = w2; >+ iii++; >+ if (Verbose > 1 && loop % 1024 == 0) >+ dolog(LOG_DEBUG, "w1 %d w2 %d", w1, w2); >+ } >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "left_input_total %ld right_input_total %ld", left_input_total, right_input_total); >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "min_left_val %d max_left_val %d", min_left_val, max_left_val); >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "min_right_val %d max_right_val %d", min_right_val, max_right_val); >+ dc_offset_left = (float) ((double) left_input_total / (double) (Process_Frames)); >+ dc_offset_right = (float) ((double) right_input_total / (double) (Process_Frames)); >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "dc_offset_left %8.3f dc_offset_right %8.3f", dc_offset_left, dc_offset_right); >+ char bit = 0; >+ if (Entropy_Filter == 0) // new style Entropy_Filter for entropy >+ { for (iii = 0; iii < Process_Frames - 2; iii++) >+ { int32_t w1, w2; >+ float leftval, rightval, delta [3]; >+ int jjj; >+ for (jjj = 0; jjj < 3; jjj++) >+ { w1 = left_processed_samples [iii + jjj]; >+ w2 = right_processed_samples [iii + jjj]; >+ leftval = ((float) w1 - dc_offset_left); >+ if (leftval < 0.) >+ leftval = leftval / (dc_offset_left - (float) min_left_val); >+ else >+ leftval = leftval / ((float) max_left_val - dc_offset_left); >+ rightval = ((float) w2 - dc_offset_right); >+ if (rightval < 0.) >+ rightval = rightval / (dc_offset_right - (float) min_right_val); >+ else >+ rightval = rightval / ((float) max_right_val - dc_offset_right); >+ delta [jjj] = fabs (leftval - rightval); >+ } >+ if (delta [1] - delta [0] < 0. && delta [2] - delta [1] > 0.) >+ { bit = 0; >+ } else if (delta [1] - delta [0] > 0. && delta [2] - delta [1] < 0.) >+ { bit = 1; >+ } else >+ bit = -1; >+ if (bit != -1) >+ add_entropy_bit (bit, output_buffer, n_output_bytes); >+ } >+ } >+ else if (Entropy_Filter == 1) // new style Entropy_Filter for entropy with second difference == 0, higher hurdle >+ { for (iii = 0; iii < Process_Frames - 2; iii++) >+ { int32_t w1, w2; >+ float leftval, rightval, delta [3]; >+ int jjj; >+ for (jjj = 0; jjj < 3; jjj++) >+ { w1 = left_processed_samples [iii + jjj]; >+ w2 = right_processed_samples [iii + jjj]; >+ leftval = ((float) w1 - dc_offset_left); >+ if (leftval < 0.) >+ leftval = leftval / (dc_offset_left - (float) min_left_val); >+ else >+ leftval = leftval / ((float) max_left_val - dc_offset_left); >+ rightval = ((float) w2 - dc_offset_right); >+ if (rightval < 0.) >+ rightval = rightval / (dc_offset_right - (float) min_right_val); >+ else >+ rightval = rightval / ((float) max_right_val - dc_offset_right); >+ delta [jjj] = fabs (leftval - rightval); >+ } >+ if (delta [1] - delta [0] < 0. && delta [2] - delta [1] > 0. && delta [2] - delta [0] == 0.) >+ { bit = 0; >+ } else if (delta [1] - delta [0] > 0. && delta [2] - delta [1] < 0. && delta [2] - delta [0] == 0.) >+ { bit = 1; >+ } else >+ bit = -1; >+ if (bit != -1) >+ add_entropy_bit (bit, output_buffer, n_output_bytes); >+ } >+ } >+ else if (Entropy_Filter == 2) // new style Entropy_Filter for entropy with second difference != 0, higher hurdle >+ { for (iii = 0; iii < Process_Frames - 2; iii++) >+ { int32_t w1, w2; >+ float leftval, rightval, delta [3]; >+ int jjj; >+ for (jjj = 0; jjj < 3; jjj++) >+ { w1 = left_processed_samples [iii + jjj]; >+ w2 = right_processed_samples [iii + jjj]; >+ leftval = ((float) w1 - dc_offset_left); >+ if (leftval < 0.) >+ leftval = leftval / (dc_offset_left - (float) min_left_val); >+ else >+ leftval = leftval / ((float) max_left_val - dc_offset_left); >+ rightval = ((float) w2 - dc_offset_right); >+ if (rightval < 0.) >+ rightval = rightval / (dc_offset_right - (float) min_right_val); >+ else >+ rightval = rightval / ((float) max_right_val - dc_offset_right); >+ delta [jjj] = fabs (leftval - rightval); >+ } >+ if (delta [1] - delta [0] < 0. && delta [2] - delta [1] > 0. && delta [2] - delta [0] != 0.) >+ { bit = 0; >+ } else if (delta [1] - delta [0] > 0. && delta [2] - delta [1] < 0. && delta [2] - delta [0] != 0.) >+ { bit = 1; >+ } else >+ bit = -1; >+ if (bit != -1) >+ add_entropy_bit (bit, output_buffer, n_output_bytes); >+ } >+ } >+ else if (Entropy_Filter == 10) // original style Entropy_Filter for entropy >+ { for (iii = 0; iii < Process_Frames - 1; iii+=2) >+ { int32_t w1, w2, w3, w4; >+ w1 = left_processed_samples [iii]; >+ w2 = right_processed_samples [iii]; >+ w3 = left_processed_samples [iii + 1]; >+ w4 = right_processed_samples [iii + 1]; >+ /* Determine order of channels for each sample, subtract previous sample >+ * to compensate for unbalanced audio devices */ >+ o1 = order(w1-psl, w2-psr); >+ o2 = order(w3-psl, w4-psr); >+ if (a > 0) >+ { psl = w3; >+ psr = w4; >+ } >+ else >+ { psl = w1; >+ psr = w2; >+ } >+ /* If both samples have the same order, there is bias in the samples, so we >+ * discard them; if both channels are equal on either sample, we discard >+ * them too; additionally, alternate the sample we'll use next (even more >+ * bias removal) */ >+ if (o1 == o2 || o1 < 0 || o2 < 0) >+ { a = -a; >+ } >+ else >+ { /* We've got a random bit; the bit is either the order from the first or >+ * the second sample, determined by the alternator 'a' */ >+ bit = (a > 0) ? o1 : o2; >+ } >+ if (bit != -1) >+ add_entropy_bit (bit, output_buffer, n_output_bytes); >+ } >+ } >+ else if (Entropy_Filter == 11) // original style Entropy_Filter for entropy but using dc_offset values for bias elimination >+ { for (iii = 0; iii < Process_Frames - 1; iii+=2) >+ { int32_t w1, w2, w3, w4; >+ w1 = left_processed_samples [iii]; >+ w2 = right_processed_samples [iii]; >+ w3 = left_processed_samples [iii + 1]; >+ w4 = right_processed_samples [iii + 1]; >+ /* Determine order of channels for each sample, subtract previous sample >+ * to compensate for unbalanced audio devices */ >+ o1 = order(w1-dc_offset_left, w2-dc_offset_right); >+ o2 = order(w3-dc_offset_left, w4-dc_offset_right); >+ /* If both samples have the same order, there is bias in the samples, so we >+ * discard them; if both channels are equal on either sample, we discard >+ * them too; additionally, alternate the sample we'll use next (even more >+ * bias removal) */ >+ if (o1 == o2 || o1 < 0 || o2 < 0) >+ { a = -a; >+ } >+ else >+ { /* We've got a random bit; the bit is either the order from the first or >+ * the second sample, determined by the alternator 'a' */ >+ bit = (a > 0) ? o1 : o2; >+ } >+ if (bit != -1) >+ add_entropy_bit (bit, output_buffer, n_output_bytes); >+ } >+ } >+ if (Verbose > 1) >+ dolog(LOG_DEBUG, "get_random_data() finished"); >+} > >- if (verbose > 1) >- dolog(LOG_DEBUG, "get_random_data() finished"); >+void add_entropy_bit (char bit, unsigned char *output_buffer, int *n_output_bytes) >+{ >+ static int bits_out=0; >+ static unsigned char byte_out=0; > >- free(input_buffer); >+ byte_out <<= 1; >+ byte_out += bit; >+ bits_out++; >+ if (bits_out>=8) >+ { if (Error_State == 0 || Internal_Test == 1) >+ { (output_buffer)[*n_output_bytes]=byte_out; >+ (*n_output_bytes)++; >+ } >+ bits_out=0; >+ RNGTEST_add(byte_out); >+ if (Internal_Test == 1 && RNGTEST() == -1) >+ { if (Error_State == 0) >+ dolog(LOG_CRIT, "test of random data failed, skipping %d bytes before re-using data-stream (%d bytes in flush)", RNGTEST_PENALTY, Error_State); >+ Error_State = RNGTEST_PENALTY; >+ *n_output_bytes = 0; >+ } else >+ { if (Error_State > 0) >+ { Error_State--; >+ if (Error_State == 0) >+ dolog(LOG_INFO, "Restarting fetching of entropy data"); >+ } >+ } >+ } > } > > void usage(void) > { >- fprintf(stderr, "Usage: audio-entropyd [options]\n\n"); >- fprintf(stderr, "Collect entropy from a soundcard and feed it into the kernel random pool.\n"); >- fprintf(stderr, "\n"); >- fprintf(stderr, "Options:\n"); >- fprintf(stderr, "--device, -d [] Specify sound device to use. (Default %s)\n", cdevice); >- fprintf(stderr, "--sample-rate, -N [] Audio sampling rate. (default %i)\n", DEFAULT_SAMPLE_RATE); >- fprintf(stderr, "--skip-test, -s Do not check if data is random enough.\n"); >- fprintf(stderr, "--do-not-fork -n Do not fork.\n"); >- fprintf(stderr, "--verbose, -v Be verbose.\n"); >- fprintf(stderr, "--help, -h This help.\n"); >- fprintf(stderr, "\n"); >+ fprintf(stderr, "Usage: audio-entropyd [options]\n\n"); >+ fprintf(stderr, "Collect entropy from a soundcard and feed it into the kernel random pool.\n"); >+ fprintf(stderr, "\n"); >+ fprintf(stderr, "Options:\n"); >+ fprintf(stderr, "--device, -d [] Specify sound device to use. (Default %s)\n", Capture_Device); >+ fprintf(stderr, "--entropy_filter, -e [] Audio sampling rate. (default %i)\n", Entropy_Filter); >+ fprintf(stderr, "--sample-rate, -r [] Audio sampling rate. (default %i)\n", DEFAULT_FRAME_RATE); >+ fprintf(stderr, "--sample-size, -z [] Audio sampling rate. (default %i)\n", DEFAULT_SAMPLE_SIZE); >+ fprintf(stderr, "--skip-test, -s Do not check if data is random enough.\n"); >+ fprintf(stderr, "--do-not-fork -n Do not fork.\n"); >+ fprintf(stderr, "--verbose, -v Be Verbose.\n"); >+ fprintf(stderr, "--help, -h This help.\n"); >+ fprintf(stderr, "\n"); > } > > void daemonise(void) > { >- if (become_daemon() == -1) >- error_exit("cannot fork into the background"); >+ if (become_daemon() == -1) >+ error_exit("cannot fork into the background"); > >- if (write_pidfile(PID_FILE) == -1) >- error_exit("Couldn't open PID file \"%s\" for writing: %m.", PID_FILE); >+ if (write_pidfile(PID_FILE) == -1) >+ error_exit("Couldn't open PID file \"%s\" for writing: %m.", PID_FILE); > } > > void gracefully_exit(int signum) > { >- if (munlockall() == -1) >- error_exit("problem unlocking pages"); >- unlink(PID_FILE); >- dolog(LOG_NOTICE, "audio-entropyd stopping due to signal %d", signum); >- exit(0); >+ if (munlockall() == -1) >+ error_exit("problem unlocking pages"); >+ unlink(PID_FILE); >+ dolog(LOG_NOTICE, "audio-entropyd stopping due to signal %d", signum); >+ exit(0); > } > > void logging_handler(int signum) > { >- if (signum == SIGUSR1) >- { >- loggingstate = 1; >- dolog(LOG_WARNING, "Currently in flush state: entropy data is not random enough"); >- } >+ if (signum == SIGUSR1) >+ { >+ loggingstate = 1; >+ dolog(LOG_WARNING, "Currently in flush state: entropy data is not random enough"); >+ } > >- if (signum == SIGUSR2) >- loggingstate = 0; >+ if (signum == SIGUSR2) >+ loggingstate = 0; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 982660
:
815407
|
815408
|
815823
|
815824
|
869266
|
869267
|
869681
|
869682
|
871083
|
871096