X-Git-Url: http://git.meshlink.io/?p=meshlink;a=blobdiff_plain;f=src%2Fcrypto.c;h=3244a0b4628bdd2e6ddb6f49dbf1a0c30fab17ad;hp=cf000c8a0824f855a1f6e6815603e00500c6ed33;hb=963c5055505f2fc117cd5efa06eaa02c9b2bf85d;hpb=0afa91b3c4f62db18c715e8499368a7c2c9ee5bd diff --git a/src/crypto.c b/src/crypto.c index cf000c8a..3244a0b4 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -23,12 +23,19 @@ //TODO: use a strict random source once to seed a PRNG? +#ifndef HAVE_MINGW + static int random_fd = -1; void crypto_init(void) { + assert(random_fd == -1); + random_fd = open("/dev/urandom", O_RDONLY); - if(random_fd < 0) + + if(random_fd < 0) { random_fd = open("/dev/random", O_RDONLY); + } + if(random_fd < 0) { fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); abort(); @@ -36,11 +43,57 @@ void crypto_init(void) { } void crypto_exit(void) { + assert(random_fd != -1); + + close(random_fd); + random_fd = -1; +} + +void randomize(void *out, size_t outlen) { + assert(outlen); + + char *ptr = out; + + while(outlen) { + size_t len = read(random_fd, ptr, outlen); + + if(len <= 0) { + if(errno == EAGAIN || errno == EINTR) { + continue; + } + + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); + abort(); + } + + ptr += len; + outlen -= len; + } +} + +#else + +#include +HCRYPTPROV prov; + +void crypto_init(void) { + if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + fprintf(stderr, "CryptAcquireContext() failed!\n"); + abort(); + } +} + +void crypto_exit(void) { + CryptReleaseContext(prov, 0); } void randomize(void *out, size_t outlen) { - if(read(random_fd, out, outlen) != outlen) { - fprintf(stderr, "Error reading random numbers: %s\n", strerror(errno)); + assert(outlen); + + if(!CryptGenRandom(prov, outlen, out)) { + fprintf(stderr, "CryptGenRandom() failed\n"); abort(); } } + +#endif