X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fopenssl%2Fcrypto.c;h=5c7573602651ccbead9d63ed3c2a4765c686f407;hb=046a10d692d1ac22de4daf783ee4fe025c4eb6ec;hp=7e6e9f62fcaece3e0a328480fa0fe47ef1f0ef74;hpb=7ea85043ac1fb2096baea44f6b0af27ac0d0b2cf;p=tinc diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index 7e6e9f62..5c757360 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -1,6 +1,6 @@ /* crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2021 Guus Sliepen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,34 +12,106 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include #include -#include "crypto.h" +#include "../crypto.h" + +#ifndef HAVE_MINGW + +static int random_fd = -1; -void crypto_init() { - RAND_load_file("/dev/urandom", 1024); +static void random_init(void) { + random_fd = open("/dev/urandom", O_RDONLY); - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); + if(random_fd < 0) { + random_fd = open("/dev/random", O_RDONLY); + } - OpenSSL_add_all_algorithms(); + if(random_fd < 0) { + fprintf(stderr, "Could not open source of random numbers: %s\n", strerror(errno)); + abort(); + } } -void crypto_exit() { - EVP_cleanup(); +static void random_exit(void) { + close(random_fd); +} + +void randomize(void *vout, size_t outlen) { + char *out = vout; + + while(outlen) { + ssize_t len = read(random_fd, out, outlen); + + if(len <= 0) { + if(len == -1 && (errno == EAGAIN || errno == EINTR)) { + continue; + } + + fprintf(stderr, "Could not read random numbers: %s\n", strerror(errno)); + abort(); + } + + out += len; + outlen -= len; + } +} + +#else + +#include +HCRYPTPROV prov; + +void random_init(void) { + if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + fprintf(stderr, "CryptAcquireContext() failed!\n"); + abort(); + } +} + +void random_exit(void) { + CryptReleaseContext(prov, 0); } void randomize(void *out, size_t outlen) { - RAND_pseudo_bytes(out, outlen); + if(!CryptGenRandom(prov, outlen, out)) { + fprintf(stderr, "CryptGenRandom() failed\n"); + abort(); + } +} + +#endif + +void crypto_init(void) { + random_init(); + + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); +#if OPENSSL_API_COMPAT < 0x10100000L + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); +#endif + + if(!RAND_status()) { + fprintf(stderr, "Not enough entropy for the PRNG!\n"); + abort(); + } +} + +void crypto_exit(void) { +#if OPENSSL_API_COMPAT < 0x10100000L + EVP_cleanup(); + ERR_free_strings(); + ENGINE_cleanup(); +#endif + random_exit(); }