From 6a40b61b9f6560ac8d6251a30b58bdb87d5cdb27 Mon Sep 17 00:00:00 2001
From: KO Myung-Hun <komh@chollian.net>
Date: Thu, 15 Dec 2011 17:13:10 +0900
Subject: [PATCH 8/8] Implement vlc_rand_bytes() for OS/2

---
 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 ab79435..93cb0d1 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 3b84de6..0c6ab65 100644
--- a/src/misc/rand.c
+++ b/src/misc/rand.c
@@ -26,144 +26,6 @@
 #include <vlc_common.h>
 #include <vlc_rand.h>
 
-#ifndef WIN32
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <vlc_fs.h>
-
-#include <vlc_md5.h>
-
-/*
- * 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 <wincrypt.h>
-
-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 0000000..c214ac1
--- /dev/null
+++ b/src/os2/rand.c
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * rand.c : non-predictible random bytes generator
+ *****************************************************************************
+ * Copyright (C) 2011 KO Myung-Hun <komh@chollian.net>
+ *
+ * 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 <vlc_common.h>
+#include <vlc_rand.h>
+
+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 0000000..fbf020f
--- /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 <vlc_common.h>
+#include <vlc_rand.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <vlc_fs.h>
+
+#include <vlc_md5.h>
+
+/*
+ * 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 0000000..aff6012
--- /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 <vlc_common.h>
+#include <vlc_rand.h>
+
+#include <wincrypt.h>
+
+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);
+    }
+}
-- 
1.7.3.2

