tech-security archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Correction.



Sorry, last version was still sending output to stdout. This one is writing directly to /dev/urandom


/*
Public Domain, please append your contributions, respectfully.
Version 1.0 - Sylvain Saucier (sylvain%sysau.com@localhost) - Original author
Slight variation to make this program reseed urandom from userspace in NetBSD.
The use case for this would be during an installation on a machine without 
proper hardware entropy sources.
*/

#include <stdint.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct {
volatile uint64_t * s_output;
volatile uint64_t * s_input;
pthread_t thread;
} _C4_node;

typedef struct {
volatile uint64_t shared_io[3];
_C4_node t[3];
long num_threads;
} _C4_state;

int C4_hash_algo(volatile uint64_t * in, volatile uint64_t * out) {
uint64_t acc = 1;
uint64_t primes[128] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107,
109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 
181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 
257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 
337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 
419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 
491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 
587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647};
for (int bit = 0; bit < 64; bit++) {
* in = ( * in << 13) | ( * in >> (64 - 13));
acc = (acc << bit) | (acc >> (64 - bit));
acc *= primes[(2 * bit) + (1 & * in)];* out += acc ^ * in;
}* out ^= acc;
return 0;
}

void * C4_main(void * raw) {
_C4_node * self__C4_state = (_C4_node * ) raw;
while (1) {
C4_hash_algo(self__C4_state -> s_output, self__C4_state -> s_input);
}
return NULL;
}

void init(_C4_state * s, long _numt) {
for (int thr = 0; thr < _numt; thr++) {
s -> num_threads = _numt;
s -> shared_io[thr] = 0;
s -> t[thr].s_output = & (s -> shared_io[thr]);
s -> t[thr].s_input = & (s -> shared_io[(thr + 1) % _numt]);
pthread_create( & (s -> t[thr].thread), NULL, & C4_main, & (s -> t[thr]));
}
}

int main(int argc, const char * argv[]) {
uint64_t out;
_C4_state state;
long nproc = sysconf(_SC_NPROCESSORS_ONLN);
size_t buf_len = 1024;
char* userinput[buf_len];

if ( nproc < 2 ) {
fprintf(stderr, "Insufficient number of cores to sustain synthetic chaos effect.\n");
exit(EXIT_FAILURE);
};

init( & state, nproc > 2 ? 2 : nproc); //It is better to drive two theads simultaneously than three threads on two cores.

FILE* urandom = fopen("/dev/urandom", "a");
if ( urandom == NULL ) {
fprintf(stderr, "Cannot open /dev/urandom.\n");
exit(EXIT_FAILURE);
}

for ( int x = 0 ; x < 4 ; x++ ) { //Obtain 256 bits of entropy
usleep(1000); //I observed decorrelation using 5 microseconds, 1 milliseconds should be good enough to provide last resort entropy.
out = 0; // do not reuse old entropy.
for (int thr = 0; thr < state.num_threads; thr++) {
out ^= state.shared_io[thr];
}
if ( fwrite( & out, sizeof(uint64_t), 1, urandom) != 1 ) {
fprintf(stderr, "/dev/urandom write error.\n");
exit(EXIT_FAILURE);
}
}
fclose(urandom);
exit(EXIT_SUCCESS);
}

Attachment: signature.asc
Description: Message signed with OpenPGP



Home | Main Index | Thread Index | Old Index