From bac71d2759727a7cf198e8241a345cfa2b6dbd9a Mon Sep 17 00:00:00 2001 From: KO Myung-Hun Date: Thu, 15 Dec 2011 17:13:10 +0900 Subject: [PATCH] Implement vlc_rand_bytes() for OS/2 and split to different files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont --- src/Makefile.am | 6 +++ src/misc/rand.c | 138 ----------------------------------------------- src/os2/rand.c | 40 ++++++++++++++ src/posix/rand.c | 122 +++++++++++++++++++++++++++++++++++++++++ src/win32/rand.c | 66 +++++++++++++++++++++++ 5 files changed, 234 insertions(+), 138 deletions(-) create mode 100644 src/os2/rand.c create mode 100644 src/posix/rand.c create mode 100644 src/win32/rand.c diff --git a/src/Makefile.am b/src/Makefile.am index ab79435e02..93cb0d1117 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -246,6 +246,7 @@ SOURCES_libvlc_darwin = \ network/poll.c \ posix/thread.c \ posix/darwin_specific.c \ + posix/rand.c \ $(NULL) SOURCES_libvlc_linux = \ @@ -256,6 +257,7 @@ SOURCES_libvlc_linux = \ network/poll.c \ posix/thread.c \ posix/linux_specific.c \ + posix/rand.c \ $(NULL) SOURCES_libvlc_win32 = \ @@ -267,6 +269,7 @@ SOURCES_libvlc_win32 = \ win32/thread.c \ win32/specific.c \ win32/winsock.c \ + win32/rand.c \ $(NULL) SOURCES_libvlc_symbian = \ @@ -274,6 +277,7 @@ SOURCES_libvlc_symbian = \ symbian/dirs.c \ misc/atomic.c \ win32/plugin.c \ + posix/rand.c \ $(NULL) SOURCES_libvlc_os2 = \ @@ -285,6 +289,7 @@ SOURCES_libvlc_os2 = \ os2/poll.c \ os2/thread.c \ os2/specific.c \ + os2/rand.c \ $(NULL) SOURCES_libvlc_other = \ @@ -294,6 +299,7 @@ SOURCES_libvlc_other = \ network/poll.c \ posix/thread.c \ posix/specific.c \ + posix/rand.c \ $(NULL) SOURCES_libvlc_common = \ diff --git a/src/misc/rand.c b/src/misc/rand.c index 3b84de6364..0c6ab65146 100644 --- a/src/misc/rand.c +++ b/src/misc/rand.c @@ -26,144 +26,6 @@ #include #include -#ifndef WIN32 -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -/* - * Pseudo-random number generator using a HMAC-MD5 in counter mode. - * Probably not very secure (expert patches welcome) but definitely - * better than rand() which is defined to be reproducible... - */ -#define BLOCK_SIZE 64 - -static uint8_t okey[BLOCK_SIZE], ikey[BLOCK_SIZE]; - -static void vlc_rand_init (void) -{ -#if defined (__OpenBSD__) || defined (__OpenBSD_kernel__) - static const char randfile[] = "/dev/random"; -#else - static const char randfile[] = "/dev/urandom"; -#endif - uint8_t key[BLOCK_SIZE]; - - /* Get non-predictible value as key for HMAC */ - int fd = vlc_open (randfile, O_RDONLY); - if (fd == -1) - return; /* Uho! */ - - for (size_t i = 0; i < sizeof (key);) - { - ssize_t val = read (fd, key + i, sizeof (key) - i); - if (val > 0) - i += val; - } - - /* Precompute outer and inner keys for HMAC */ - for (size_t i = 0; i < sizeof (key); i++) - { - okey[i] = key[i] ^ 0x5c; - ikey[i] = key[i] ^ 0x36; - } - - close (fd); -} - - -void vlc_rand_bytes (void *buf, size_t len) -{ - static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; - static uint64_t counter = 0; - - uint64_t stamp = NTPtime64 (); - - while (len > 0) - { - uint64_t val; - struct md5_s mdi, mdo; - - InitMD5 (&mdi); - InitMD5 (&mdo); - - pthread_mutex_lock (&lock); - if (counter == 0) - vlc_rand_init (); - val = counter++; - - AddMD5 (&mdi, ikey, sizeof (ikey)); - AddMD5 (&mdo, okey, sizeof (okey)); - pthread_mutex_unlock (&lock); - - AddMD5 (&mdi, &stamp, sizeof (stamp)); - AddMD5 (&mdi, &val, sizeof (val)); - EndMD5 (&mdi); - AddMD5 (&mdo, mdi.buf, 16); - EndMD5 (&mdo); - - if (len < 16) - { - memcpy (buf, mdo.buf, len); - break; - } - - memcpy (buf, mdo.buf, 16); - len -= 16; - buf = ((uint8_t *)buf) + 16; - } -} - -#else /* WIN32 */ - -#include - -void vlc_rand_bytes (void *buf, size_t len) -{ - HCRYPTPROV hProv; - size_t count = len; - uint8_t *p_buf = (uint8_t *)buf; - - /* fill buffer with pseudo-random data */ - while (count > 0) - { - unsigned int val; - val = rand(); - if (count < sizeof (val)) - { - memcpy (p_buf, &val, count); - break; - } - - memcpy (p_buf, &val, sizeof (val)); - count -= sizeof (val); - p_buf += sizeof (val); - } - - /* acquire default encryption context */ - if( CryptAcquireContext( - &hProv, // Variable to hold returned handle. - NULL, // Use default key container. - MS_DEF_PROV, // Use default CSP. - PROV_RSA_FULL, // Type of provider to acquire. - 0) ) - { - /* fill buffer with pseudo-random data, intial buffer content - is used as auxillary random seed */ - CryptGenRandom(hProv, len, buf); - CryptReleaseContext(hProv, 0); - } -} -#endif - static struct { bool init; diff --git a/src/os2/rand.c b/src/os2/rand.c new file mode 100644 index 0000000000..c214ac1757 --- /dev/null +++ b/src/os2/rand.c @@ -0,0 +1,40 @@ +/***************************************************************************** + * rand.c : non-predictible random bytes generator + ***************************************************************************** + * Copyright (C) 2011 KO Myung-Hun + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +void vlc_rand_bytes (void *buf, size_t len) +{ + QWORD qwTime; + uint8_t *p_buf = (uint8_t *)buf; + + while (len > 0) + { + DosTmrQueryTime( &qwTime ); + + *p_buf++ = ( uint8_t )( qwTime.ulLo * rand()); + len--; + } +} diff --git a/src/posix/rand.c b/src/posix/rand.c new file mode 100644 index 0000000000..fbf020f9c9 --- /dev/null +++ b/src/posix/rand.c @@ -0,0 +1,122 @@ +/***************************************************************************** + * rand.c : non-predictible random bytes generator + ***************************************************************************** + * Copyright © 2007 Rémi Denis-Courmont + * $Id$ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* + * Pseudo-random number generator using a HMAC-MD5 in counter mode. + * Probably not very secure (expert patches welcome) but definitely + * better than rand() which is defined to be reproducible... + */ +#define BLOCK_SIZE 64 + +static uint8_t okey[BLOCK_SIZE], ikey[BLOCK_SIZE]; + +static void vlc_rand_init (void) +{ +#if defined (__OpenBSD__) || defined (__OpenBSD_kernel__) + static const char randfile[] = "/dev/random"; +#else + static const char randfile[] = "/dev/urandom"; +#endif + uint8_t key[BLOCK_SIZE]; + + /* Get non-predictible value as key for HMAC */ + int fd = vlc_open (randfile, O_RDONLY); + if (fd == -1) + return; /* Uho! */ + + for (size_t i = 0; i < sizeof (key);) + { + ssize_t val = read (fd, key + i, sizeof (key) - i); + if (val > 0) + i += val; + } + + /* Precompute outer and inner keys for HMAC */ + for (size_t i = 0; i < sizeof (key); i++) + { + okey[i] = key[i] ^ 0x5c; + ikey[i] = key[i] ^ 0x36; + } + + close (fd); +} + + +void vlc_rand_bytes (void *buf, size_t len) +{ + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + static uint64_t counter = 0; + + uint64_t stamp = NTPtime64 (); + + while (len > 0) + { + uint64_t val; + struct md5_s mdi, mdo; + + InitMD5 (&mdi); + InitMD5 (&mdo); + + pthread_mutex_lock (&lock); + if (counter == 0) + vlc_rand_init (); + val = counter++; + + AddMD5 (&mdi, ikey, sizeof (ikey)); + AddMD5 (&mdo, okey, sizeof (okey)); + pthread_mutex_unlock (&lock); + + AddMD5 (&mdi, &stamp, sizeof (stamp)); + AddMD5 (&mdi, &val, sizeof (val)); + EndMD5 (&mdi); + AddMD5 (&mdo, mdi.buf, 16); + EndMD5 (&mdo); + + if (len < 16) + { + memcpy (buf, mdo.buf, len); + break; + } + + memcpy (buf, mdo.buf, 16); + len -= 16; + buf = ((uint8_t *)buf) + 16; + } +} diff --git a/src/win32/rand.c b/src/win32/rand.c new file mode 100644 index 0000000000..aff6012178 --- /dev/null +++ b/src/win32/rand.c @@ -0,0 +1,66 @@ +/***************************************************************************** + * rand.c : non-predictible random bytes generator + ***************************************************************************** + * Copyright © 2007 Rémi Denis-Courmont + * $Id$ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include + +void vlc_rand_bytes (void *buf, size_t len) +{ + HCRYPTPROV hProv; + size_t count = len; + uint8_t *p_buf = (uint8_t *)buf; + + /* fill buffer with pseudo-random data */ + while (count > 0) + { + unsigned int val; + val = rand(); + if (count < sizeof (val)) + { + memcpy (p_buf, &val, count); + break; + } + + memcpy (p_buf, &val, sizeof (val)); + count -= sizeof (val); + p_buf += sizeof (val); + } + + /* acquire default encryption context */ + if( CryptAcquireContext( + &hProv, // Variable to hold returned handle. + NULL, // Use default key container. + MS_DEF_PROV, // Use default CSP. + PROV_RSA_FULL, // Type of provider to acquire. + 0) ) + { + /* fill buffer with pseudo-random data, intial buffer content + is used as auxillary random seed */ + CryptGenRandom(hProv, len, buf); + CryptReleaseContext(hProv, 0); + } +}