Line data Source code
1 : #include "passgen/assert.h" 2 : #include "passgen/config.h" 3 : #include "passgen/random.h" 4 : #include "passgen/util/endian.h" 5 : #include <stdlib.h> 6 : #include <string.h> 7 : 8 : static const char *passgen_random_default_device = "/dev/urandom"; 9 : 10 : #ifdef __linux__ 11 : #define PASSGEN_RANDOM_HAVE_SYSTEM 12 : #include <sys/random.h> 13 : 14 : static size_t 15 56497 : passgen_random_system_read(void *context, void *dest, size_t size) { 16 : (void) context; 17 56497 : return getrandom(dest, size, 0); 18 : } 19 : #endif 20 : 21 : #ifdef __APPLE__ 22 : #define PASSGEN_RANDOM_HAVE_SYSTEM 23 : 24 : static size_t 25 : passgen_random_system_read(void *context, void *dest, size_t size) { 26 : (void) context; 27 : arc4random_buf(dest, size); 28 : return size; 29 : } 30 : #endif 31 : 32 5 : static size_t passgen_random_read_file(void *context, void *dest, size_t size) { 33 5 : return fread(dest, 1, size, context); 34 : } 35 : 36 5 : static void passgen_random_close_file(void *context) { 37 5 : fclose(context); 38 5 : } 39 : 40 17 : static void passgen_random_system_close(void *context) { 41 : (void) context; 42 17 : } 43 : 44 53 : passgen_random *passgen_random_system_open(passgen_random *random) { 45 : #ifdef PASSGEN_RANDOM_HAVE_SYSTEM 46 53 : if(!random) { 47 5 : random = malloc(sizeof(passgen_random)); 48 5 : if(!random) return NULL; 49 : } 50 : 51 53 : random->context = NULL; 52 53 : random->read = passgen_random_system_read; 53 53 : random->close = passgen_random_system_close; 54 53 : passgen_random_reload(random); 55 : #else 56 : passgen_random *rand = 57 : passgen_random_path_open(random, passgen_random_default_device); 58 : if(!rand) { 59 : fprintf( 60 : stderr, 61 : "error: cannot open system randomness device '%s'\n", 62 : passgen_random_default_device); 63 : } 64 : #endif 65 53 : return random; 66 : } 67 : 68 : passgen_random * 69 9 : passgen_random_path_open(passgen_random *random, const char *path) { 70 9 : FILE *device = fopen(path, "r"); 71 9 : if(!device) { 72 5 : return NULL; 73 : } 74 : 75 4 : if(!random) { 76 2 : random = malloc(sizeof(passgen_random)); 77 2 : if(!random) return NULL; 78 : } 79 : 80 4 : return passgen_random_file_open(random, device); 81 : 82 : passgen_random_reload(random); 83 : 84 : return random; 85 : } 86 : 87 5 : passgen_random *passgen_random_file_open(passgen_random *random, FILE *file) { 88 5 : if(!random) { 89 1 : random = malloc(sizeof(passgen_random)); 90 1 : if(!random) return NULL; 91 : } 92 : 93 5 : random->context = file; 94 5 : random->read = passgen_random_read_file; 95 5 : random->close = passgen_random_close_file; 96 5 : passgen_random_reload(random); 97 5 : return random; 98 : }