summaryrefslogtreecommitdiff
path: root/boost/uuid
diff options
context:
space:
mode:
Diffstat (limited to 'boost/uuid')
-rw-r--r--boost/uuid/basic_name_generator.hpp2
-rw-r--r--boost/uuid/detail/random_provider.hpp75
-rw-r--r--boost/uuid/detail/random_provider_arc4random.ipp32
-rw-r--r--boost/uuid/detail/random_provider_bcrypt.ipp79
-rw-r--r--boost/uuid/detail/random_provider_detect_platform.hpp62
-rw-r--r--boost/uuid/detail/random_provider_getentropy.ipp37
-rw-r--r--boost/uuid/detail/random_provider_include_platform.hpp27
-rw-r--r--boost/uuid/detail/random_provider_posix.ipp95
-rw-r--r--boost/uuid/detail/random_provider_wincrypt.ipp82
-rw-r--r--boost/uuid/detail/seed_rng.hpp320
-rw-r--r--boost/uuid/entropy_error.hpp45
-rw-r--r--boost/uuid/name_generator.hpp2
-rw-r--r--boost/uuid/name_generator_md5.hpp2
-rw-r--r--boost/uuid/name_generator_sha1.hpp2
-rw-r--r--boost/uuid/random_generator.hpp105
-rw-r--r--boost/uuid/seed_rng.hpp16
16 files changed, 621 insertions, 362 deletions
diff --git a/boost/uuid/basic_name_generator.hpp b/boost/uuid/basic_name_generator.hpp
index c867fbd266..e82b5f92bb 100644
--- a/boost/uuid/basic_name_generator.hpp
+++ b/boost/uuid/basic_name_generator.hpp
@@ -1,7 +1,7 @@
// Boost basic_name_generator.hpp header file -----------------------//
// Copyright 2010 Andy Tompkins.
-// Copyright 2017 James E. King, III
+// Copyright 2017 James E. King III
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
diff --git a/boost/uuid/detail/random_provider.hpp b/boost/uuid/detail/random_provider.hpp
new file mode 100644
index 0000000000..03d8f26f95
--- /dev/null
+++ b/boost/uuid/detail/random_provider.hpp
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2017 James E. King III
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENCE_1_0.txt)
+//
+// Platform-specific random entropy provider
+//
+
+#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP
+#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP
+
+#include <boost/core/noncopyable.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/limits.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+#include <boost/uuid/entropy_error.hpp>
+#include <climits>
+#include <iterator>
+
+// Detection of the platform is separated from inclusion of the correct
+// header to facilitate mock testing of the provider implementations.
+
+#include <boost/uuid/detail/random_provider_detect_platform.hpp>
+#include <boost/uuid/detail/random_provider_include_platform.hpp>
+
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+//! \brief Contains code common to all random_provider implementations.
+//! \note random_provider_base is required to provide this method:
+//! void get_random_bytes(void *buf, size_t siz);
+//! \note noncopyable because of some base implementations so
+//! this makes it uniform across platforms to avoid any
+//! porting surprises
+class random_provider
+ : public detail::random_provider_base,
+ public noncopyable
+{
+public:
+ //! Leverage the provider as a SeedSeq for
+ //! PseudoRandomNumberGeneration seeing.
+ //! \note: See Boost.Random documentation for more details
+ template<class Iter>
+ void generate(Iter first, Iter last)
+ {
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
+ BOOST_STATIC_ASSERT(is_integral<value_type>::value);
+ BOOST_STATIC_ASSERT(is_unsigned<value_type>::value);
+ BOOST_STATIC_ASSERT(sizeof(value_type) * CHAR_BIT >= 32);
+
+ for (; first != last; ++first)
+ {
+ get_random_bytes(&*first, sizeof(*first));
+ *first &= (std::numeric_limits<boost::uint32_t>::max)();
+ }
+ }
+
+ //! Return the name of the selected provider
+ const char * name() const
+ {
+ return BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(BOOST_UUID_RANDOM_PROVIDER_NAME);
+ }
+};
+
+} // detail
+} // uuids
+} // boost
+
+#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP
diff --git a/boost/uuid/detail/random_provider_arc4random.ipp b/boost/uuid/detail/random_provider_arc4random.ipp
new file mode 100644
index 0000000000..6facf28718
--- /dev/null
+++ b/boost/uuid/detail/random_provider_arc4random.ipp
@@ -0,0 +1,32 @@
+//
+// Copyright (c) 2017 James E. King III
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENCE_1_0.txt)
+//
+// "A Replacement Call for Random"
+// https://man.openbsd.org/arc4random.3
+//
+
+#include <stdlib.h>
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+class random_provider_base
+{
+ public:
+ //! Obtain entropy and place it into a memory location
+ //! \param[in] buf the location to write entropy
+ //! \param[in] siz the number of bytes to acquire
+ void get_random_bytes(void *buf, size_t siz)
+ {
+ arc4random_buf(buf, siz);
+ }
+};
+
+} // detail
+} // uuids
+} // boost
diff --git a/boost/uuid/detail/random_provider_bcrypt.ipp b/boost/uuid/detail/random_provider_bcrypt.ipp
new file mode 100644
index 0000000000..8fedf67b53
--- /dev/null
+++ b/boost/uuid/detail/random_provider_bcrypt.ipp
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2017 James E. King III
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENCE_1_0.txt)
+//
+// BCrypt provider for entropy
+//
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/winapi/bcrypt.hpp>
+#include <boost/winapi/get_last_error.hpp>
+#include <boost/throw_exception.hpp>
+
+#if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB))
+# define BOOST_LIB_NAME "bcrypt"
+# define BOOST_AUTO_LINK_NOMANGLE
+# include <boost/config/auto_link.hpp>
+# undef BOOST_AUTO_LINK_NOMANGLE
+#endif
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+class random_provider_base
+{
+ public:
+ random_provider_base()
+ : hProv_(NULL)
+ {
+ boost::winapi::NTSTATUS_ status =
+ boost::winapi::BCryptOpenAlgorithmProvider(
+ &hProv_,
+ boost::winapi::BCRYPT_RNG_ALGORITHM_,
+ NULL,
+ 0);
+
+ if (status)
+ {
+ BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptOpenAlgorithmProvider"));
+ }
+ }
+
+ ~random_provider_base() BOOST_NOEXCEPT
+ {
+ if (hProv_)
+ {
+ ignore_unused(boost::winapi::BCryptCloseAlgorithmProvider(hProv_, 0));
+ }
+ }
+
+ //! Obtain entropy and place it into a memory location
+ //! \param[in] buf the location to write entropy
+ //! \param[in] siz the number of bytes to acquire
+ void get_random_bytes(void *buf, size_t siz)
+ {
+ boost::winapi::NTSTATUS_ status =
+ boost::winapi::BCryptGenRandom(
+ hProv_,
+ static_cast<boost::winapi::PUCHAR_>(buf),
+ boost::numeric_cast<boost::winapi::ULONG_>(siz),
+ 0);
+
+ if (status)
+ {
+ BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptGenRandom"));
+ }
+ }
+
+ private:
+ boost::winapi::BCRYPT_ALG_HANDLE_ hProv_;
+};
+
+} // detail
+} // uuids
+} // boost
diff --git a/boost/uuid/detail/random_provider_detect_platform.hpp b/boost/uuid/detail/random_provider_detect_platform.hpp
new file mode 100644
index 0000000000..497d7f42c1
--- /dev/null
+++ b/boost/uuid/detail/random_provider_detect_platform.hpp
@@ -0,0 +1,62 @@
+//
+// Copyright (c) 2017 James E. King III
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENCE_1_0.txt)
+//
+// Platform-specific random entropy provider platform detection
+//
+
+#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP
+#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP
+
+#include <boost/predef/library/c/cloudabi.h>
+#include <boost/predef/library/c/gnu.h>
+#include <boost/predef/os/bsd/open.h>
+#include <boost/predef/os/windows.h>
+
+//
+// Platform Detection - will load in the correct header and
+// will define the class <tt>random_provider_base</tt>.
+//
+
+#if BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(2, 1, 0) || BOOST_LIB_C_CLOUDABI
+# define BOOST_UUID_RANDOM_PROVIDER_ARC4RANDOM
+# define BOOST_UUID_RANDOM_PROVIDER_NAME arc4random
+
+#elif BOOST_OS_WINDOWS
+# include <boost/winapi/config.hpp>
+# if BOOST_WINAPI_PARTITION_APP_SYSTEM && \
+ !defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_WINCRYPT) && \
+ !defined(_WIN32_WCE) && \
+ (defined(BOOST_WINAPI_IS_MINGW_W64) || \
+ (BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6))
+# define BOOST_UUID_RANDOM_PROVIDER_BCRYPT
+# define BOOST_UUID_RANDOM_PROVIDER_NAME bcrypt
+
+# elif BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM
+# define BOOST_UUID_RANDOM_PROVIDER_WINCRYPT
+# define BOOST_UUID_RANDOM_PROVIDER_NAME wincrypt
+# else
+# error Unable to find a suitable windows entropy provider
+# endif
+
+#elif BOOST_LIB_C_GNU >= BOOST_VERSION_NUMBER(2, 25, 0) && !defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX)
+# define BOOST_UUID_RANDOM_PROVIDER_GETENTROPY
+# define BOOST_UUID_RANDOM_PROVIDER_NAME getentropy
+
+#else
+# define BOOST_UUID_RANDOM_PROVIDER_POSIX
+# define BOOST_UUID_RANDOM_PROVIDER_NAME posix
+
+#endif
+
+#define BOOST_UUID_RANDOM_PROVIDER_STRINGIFY2(X) #X
+#define BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(X) BOOST_UUID_RANDOM_PROVIDER_STRINGIFY2(X)
+
+#if defined(BOOST_UUID_RANDOM_PROVIDER_SHOW)
+#pragma message("BOOST_UUID_RANDOM_PROVIDER_NAME " BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(BOOST_UUID_RANDOM_PROVIDER_NAME))
+#endif
+
+#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP
diff --git a/boost/uuid/detail/random_provider_getentropy.ipp b/boost/uuid/detail/random_provider_getentropy.ipp
new file mode 100644
index 0000000000..1379bf709c
--- /dev/null
+++ b/boost/uuid/detail/random_provider_getentropy.ipp
@@ -0,0 +1,37 @@
+//
+// Copyright (c) 2017 James E. King III
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENCE_1_0.txt)
+//
+// getentropy() capable platforms
+//
+
+#include <boost/throw_exception.hpp>
+#include <cerrno>
+#include <unistd.h>
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+class random_provider_base
+{
+ public:
+ //! Obtain entropy and place it into a memory location
+ //! \param[in] buf the location to write entropy
+ //! \param[in] siz the number of bytes to acquire
+ void get_random_bytes(void *buf, size_t siz)
+ {
+ if (-1 == getentropy(buf, siz))
+ {
+ int err = errno;
+ BOOST_THROW_EXCEPTION(entropy_error(err, "getentropy"));
+ }
+ }
+};
+
+} // detail
+} // uuids
+} // boost
diff --git a/boost/uuid/detail/random_provider_include_platform.hpp b/boost/uuid/detail/random_provider_include_platform.hpp
new file mode 100644
index 0000000000..7d14ec94c0
--- /dev/null
+++ b/boost/uuid/detail/random_provider_include_platform.hpp
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2017 James E. King III
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENCE_1_0.txt)
+//
+// Platform-specific random entropy provider platform definition
+//
+
+#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP
+#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP
+
+#if defined(BOOST_UUID_RANDOM_PROVIDER_ARC4RANDOM)
+# include <boost/uuid/detail/random_provider_arc4random.ipp>
+#elif defined(BOOST_UUID_RANDOM_PROVIDER_BCRYPT)
+# include <boost/uuid/detail/random_provider_bcrypt.ipp>
+#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETENTROPY)
+# include <boost/uuid/detail/random_provider_getentropy.ipp>
+#elif defined(BOOST_UUID_RANDOM_PROVIDER_POSIX)
+# include <boost/uuid/detail/random_provider_posix.ipp>
+#elif defined(BOOST_UUID_RANDOM_PROVIDER_WINCRYPT)
+# include <boost/uuid/detail/random_provider_wincrypt.ipp>
+#endif
+
+#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP
+
diff --git a/boost/uuid/detail/random_provider_posix.ipp b/boost/uuid/detail/random_provider_posix.ipp
new file mode 100644
index 0000000000..726661c89c
--- /dev/null
+++ b/boost/uuid/detail/random_provider_posix.ipp
@@ -0,0 +1,95 @@
+/* boost uuid/detail/random_provider_posix implementation
+*
+* Copyright Jens Maurer 2000
+* Copyright 2007 Andy Tompkins.
+* Copyright Steven Watanabe 2010-2011
+* Copyright 2017 James E. King III
+*
+* Distributed under the Boost Software License, Version 1.0. (See
+* accompanying file LICENSE_1_0.txt or copy at
+* http://www.boost.org/LICENSE_1_0.txt)
+*
+* $Id$
+*/
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/uuid/entropy_error.hpp>
+#include <cerrno>
+#include <fcntl.h> // open
+#include <sys/stat.h>
+#include <sys/types.h>
+#if defined(BOOST_HAS_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE
+#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE ::close
+#endif
+#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN
+#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN ::open
+#endif
+#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ
+#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ ::read
+#endif
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+class random_provider_base
+{
+ public:
+ random_provider_base()
+ : fd_(0)
+ {
+ int flags = O_RDONLY;
+#if defined(O_CLOEXEC)
+ flags |= O_CLOEXEC;
+#endif
+ fd_ = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN("/dev/urandom", flags);
+
+ if (-1 == fd_)
+ {
+ int err = errno;
+ BOOST_THROW_EXCEPTION(entropy_error(err, "open /dev/urandom"));
+ }
+ }
+
+ ~random_provider_base() BOOST_NOEXCEPT
+ {
+ if (fd_)
+ {
+ ignore_unused(BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE(fd_));
+ }
+ }
+
+ //! Obtain entropy and place it into a memory location
+ //! \param[in] buf the location to write entropy
+ //! \param[in] siz the number of bytes to acquire
+ void get_random_bytes(void *buf, size_t siz)
+ {
+ size_t offset = 0;
+ do
+ {
+ ssize_t sz = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ(
+ fd_, static_cast<char *>(buf) + offset, siz - offset);
+
+ if (sz < 1)
+ {
+ int err = errno;
+ BOOST_THROW_EXCEPTION(entropy_error(err, "read"));
+ }
+
+ offset += sz;
+
+ } while (offset < siz);
+ }
+
+ private:
+ int fd_;
+};
+
+} // detail
+} // uuids
+} // boost
diff --git a/boost/uuid/detail/random_provider_wincrypt.ipp b/boost/uuid/detail/random_provider_wincrypt.ipp
new file mode 100644
index 0000000000..806e1e0c8b
--- /dev/null
+++ b/boost/uuid/detail/random_provider_wincrypt.ipp
@@ -0,0 +1,82 @@
+/* boost uuid/detail/random_provider_wincrypt implementation
+*
+* Copyright Jens Maurer 2000
+* Copyright 2007 Andy Tompkins.
+* Copyright Steven Watanabe 2010-2011
+* Copyright 2017 James E. King III
+*
+* Distributed under the Boost Software License, Version 1.0. (See
+* accompanying file LICENSE_1_0.txt or copy at
+* http://www.boost.org/LICENSE_1_0.txt)
+*
+* $Id$
+*/
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/winapi/crypt.hpp>
+#include <boost/winapi/get_last_error.hpp>
+#include <boost/throw_exception.hpp>
+
+#if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB))
+# if defined(_WIN32_WCE)
+# define BOOST_LIB_NAME "coredll"
+# else
+# define BOOST_LIB_NAME "advapi32"
+# endif
+# define BOOST_AUTO_LINK_NOMANGLE
+# include <boost/config/auto_link.hpp>
+# undef BOOST_AUTO_LINK_NOMANGLE
+#endif
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+class random_provider_base
+{
+ public:
+ random_provider_base()
+ : hProv_(NULL)
+ {
+ if (!boost::winapi::CryptAcquireContextW(
+ &hProv_,
+ NULL,
+ NULL,
+ boost::winapi::PROV_RSA_FULL_,
+ boost::winapi::CRYPT_VERIFYCONTEXT_ | boost::winapi::CRYPT_SILENT_))
+ {
+ boost::winapi::DWORD_ err = boost::winapi::GetLastError();
+ BOOST_THROW_EXCEPTION(entropy_error(err, "CryptAcquireContext"));
+ }
+ }
+
+ ~random_provider_base() BOOST_NOEXCEPT
+ {
+ if (hProv_)
+ {
+ ignore_unused(boost::winapi::CryptReleaseContext(hProv_, 0));
+ }
+ }
+
+ //! Obtain entropy and place it into a memory location
+ //! \param[in] buf the location to write entropy
+ //! \param[in] siz the number of bytes to acquire
+ void get_random_bytes(void *buf, size_t siz)
+ {
+ if (!boost::winapi::CryptGenRandom(hProv_,
+ boost::numeric_cast<boost::winapi::DWORD_>(siz),
+ static_cast<boost::winapi::BYTE_ *>(buf)))
+ {
+ boost::winapi::DWORD_ err = boost::winapi::GetLastError();
+ BOOST_THROW_EXCEPTION(entropy_error(err, "CryptGenRandom"));
+ }
+ }
+
+ private:
+ boost::winapi::HCRYPTPROV_ hProv_;
+};
+
+} // detail
+} // uuids
+} // boost
diff --git a/boost/uuid/detail/seed_rng.hpp b/boost/uuid/detail/seed_rng.hpp
deleted file mode 100644
index 6b7f7808db..0000000000
--- a/boost/uuid/detail/seed_rng.hpp
+++ /dev/null
@@ -1,320 +0,0 @@
-// Boost seed_rng.hpp header file ----------------------------------------------//
-
-// Copyright 2007 Andy Tompkins.
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-// Revision History
-// 09 Nov 2007 - Initial Revision
-// 25 Feb 2008 - moved to namespace boost::uuids::detail
-// 28 Nov 2009 - disabled deprecated warnings for MSVC
-// 28 Jul 2014 - fixed valgrind warnings and better entropy sources for MSVC
-
-// seed_rng models a UniformRandomNumberGenerator (see Boost.Random).
-// Random number generators are hard to seed well. This is intended to provide
-// good seed values for random number generators.
-// It creates random numbers from a sha1 hash of data from a variary of sources,
-// all of which are standard function calls. It produces random numbers slowly.
-// Peter Dimov provided the details of sha1_random_digest_().
-// see http://archives.free.net.ph/message/20070507.175609.4c4f503a.en.html
-
-#ifndef BOOST_UUID_SEED_RNG_HPP
-#define BOOST_UUID_SEED_RNG_HPP
-
-#include <boost/config.hpp>
-#include <cstring> // for memcpy
-#include <limits>
-#include <ctime> // for time_t, time, clock_t, clock
-#include <cstdlib> // for rand
-#include <cstdio> // for FILE, fopen, fread, fclose
-#include <boost/core/noncopyable.hpp>
-#include <boost/uuid/detail/sha1.hpp>
-//#include <boost/nondet_random.hpp> //forward declare boost::random::random_device
-
-// can't use boost::generator_iterator since boost::random number seed(Iter&, Iter)
-// functions need a last iterator
-//#include <boost/generator_iterator.hpp>
-# include <boost/iterator/iterator_facade.hpp>
-
-#if defined(_MSC_VER)
-# pragma warning(push) // Save warning settings.
-# pragma warning(disable : 4996) // Disable deprecated std::fopen
-#if defined(_WIN32_WCE)
-# pragma comment(lib, "coredll.lib")
-#else
-# pragma comment(lib, "advapi32.lib")
-#endif
-#endif
-
-#if defined(BOOST_WINDOWS)
-# include <boost/winapi/crypt.hpp> // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext
-# include <boost/winapi/timers.hpp>
-# include <boost/winapi/get_current_process_id.hpp>
-# include <boost/winapi/get_current_thread_id.hpp>
-#else
-# include <sys/time.h> // for gettimeofday
-# include <sys/types.h> // for pid_t
-# include <unistd.h> // for getpid()
-#endif
-
-#ifdef BOOST_NO_STDC_NAMESPACE
-namespace std {
- using ::memcpy;
- using ::time_t;
- using ::time;
- using ::clock_t;
- using ::clock;
- using ::rand;
- using ::FILE;
- using ::fopen;
- using ::fread;
- using ::fclose;
-} //namespace std
-#endif
-
-// forward declare random number generators
-namespace boost { namespace random {
-class random_device;
-}} //namespace boost::random
-
-namespace boost {
-namespace uuids {
-namespace detail {
-
-// should this be part of Boost.Random?
-class seed_rng: private boost::noncopyable
-{
-public:
- typedef unsigned int result_type;
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
-
-public:
- // note: rd_ intentionally left uninitialized
- seed_rng() BOOST_NOEXCEPT
- : rd_index_(5)
- , random_(0)
- {
-#if defined(BOOST_WINDOWS)
- if (!boost::winapi::CryptAcquireContextW(
- &random_,
- NULL,
- NULL,
- boost::winapi::PROV_RSA_FULL_,
- boost::winapi::CRYPT_VERIFYCONTEXT_ | boost::winapi::CRYPT_SILENT_))
- {
- random_ = 0;
- }
-#else
- random_ = std::fopen( "/dev/urandom", "rb" );
-#endif
-
- std::memset(rd_, 0, sizeof(rd_));
- }
-
- ~seed_rng() BOOST_NOEXCEPT
- {
- if (random_) {
-#if defined(BOOST_WINDOWS)
- boost::winapi::CryptReleaseContext(random_, 0);
-#else
- std::fclose(random_);
-#endif
- }
- }
-
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
- {
- return (std::numeric_limits<result_type>::min)();
- }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
- {
- return (std::numeric_limits<result_type>::max)();
- }
-
- result_type operator()()
- {
- if (rd_index_ >= 5) {
- //get new digest
- sha1_random_digest_();
-
- rd_index_ = 0;
- }
-
- return rd_[rd_index_++];
- }
-
-private:
- BOOST_STATIC_CONSTANT(std::size_t, internal_state_size = 5);
- inline void ignore_size(size_t) {}
-
- static unsigned int * sha1_random_digest_state_()
- {
- static unsigned int state[ internal_state_size ];
- return state;
- }
-
- void sha1_random_digest_()
- {
- boost::uuids::detail::sha1 sha;
-
-
- if (random_)
- {
- // intentionally left uninitialized
- unsigned char state[ 20 ];
-#if defined(BOOST_WINDOWS)
- boost::winapi::CryptGenRandom(random_, sizeof(state), state);
-#else
- ignore_size(std::fread( state, 1, sizeof(state), random_ ));
-#endif
- sha.process_bytes( state, sizeof( state ) );
- }
-
- {
- // Getting enropy from some system specific sources
-#if defined(BOOST_WINDOWS)
- boost::winapi::DWORD_ procid = boost::winapi::GetCurrentProcessId();
- sha.process_bytes( (unsigned char const*)&procid, sizeof( procid ) );
-
- boost::winapi::DWORD_ threadid = boost::winapi::GetCurrentThreadId();
- sha.process_bytes( (unsigned char const*)&threadid, sizeof( threadid ) );
-
- boost::winapi::LARGE_INTEGER_ ts;
- ts.QuadPart = 0;
- boost::winapi::QueryPerformanceCounter( &ts );
- sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
-
- std::time_t tm = std::time( 0 );
- sha.process_bytes( (unsigned char const*)&tm, sizeof( tm ) );
-#else
- pid_t pid = getpid();
- sha.process_bytes( (unsigned char const*)&pid, sizeof( pid ) );
-
- timeval ts;
- gettimeofday(&ts, NULL); // We do not use `clock_gettime` to avoid linkage with -lrt
- sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
-#endif
- }
-
-
- unsigned int * ps = sha1_random_digest_state_();
- sha.process_bytes( ps, internal_state_size * sizeof( unsigned int ) );
- sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) );
-
- {
- std::clock_t ck = std::clock();
- sha.process_bytes( (unsigned char const*)&ck, sizeof( ck ) );
- }
-
- {
- unsigned int rn[] =
- { static_cast<unsigned int>(std::rand())
- , static_cast<unsigned int>(std::rand())
- , static_cast<unsigned int>(std::rand())
- };
- sha.process_bytes( (unsigned char const*)rn, sizeof( rn ) );
- }
-
- {
- unsigned int * p = new unsigned int;
- sha.process_bytes( (unsigned char const*)&p, sizeof( p ) );
- delete p;
-
- const seed_rng* this_ptr = this;
- sha.process_bytes( (unsigned char const*)&this_ptr, sizeof( this_ptr ) );
- }
-
- sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) );
-
- unsigned int digest[ 5 ];
- sha.get_digest( digest );
-
- for( int i = 0; i < 5; ++i )
- {
- // harmless data race
- ps[ i ] ^= digest[ i ];
- rd_[ i ] ^= digest[ i ];
- }
- }
-
-private:
- unsigned int rd_[5];
- int rd_index_;
-
-#if defined(BOOST_WINDOWS)
- boost::winapi::HCRYPTPROV_ random_;
-#else
- std::FILE * random_;
-#endif
-};
-
-// almost a copy of boost::generator_iterator
-// but default constructor sets m_g to NULL
-template <class Generator>
-class generator_iterator
- : public iterator_facade<
- generator_iterator<Generator>
- , typename Generator::result_type
- , single_pass_traversal_tag
- , typename Generator::result_type const&
- >
-{
- typedef iterator_facade<
- generator_iterator<Generator>
- , typename Generator::result_type
- , single_pass_traversal_tag
- , typename Generator::result_type const&
- > super_t;
-
- public:
- generator_iterator() : m_g(NULL), m_value(0) {}
- generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {}
-
- void increment()
- {
- m_value = (*m_g)();
- }
-
- const typename Generator::result_type&
- dereference() const
- {
- return m_value;
- }
-
- bool equal(generator_iterator const& y) const
- {
- return this->m_g == y.m_g && this->m_value == y.m_value;
- }
-
- private:
- Generator* m_g;
- typename Generator::result_type m_value;
-};
-
-// seed() seeds a random number generator with good seed values
-
-template <typename UniformRandomNumberGenerator>
-inline void seed(UniformRandomNumberGenerator& rng)
-{
- seed_rng seed_gen;
- generator_iterator<seed_rng> begin(&seed_gen);
- generator_iterator<seed_rng> end;
- rng.seed(begin, end);
-}
-
-// random_device does not / can not be seeded
-template <>
-inline void seed<boost::random::random_device>(boost::random::random_device&) {}
-
-// random_device does not / can not be seeded
-template <>
-inline void seed<seed_rng>(seed_rng&) {}
-
-}}} //namespace boost::uuids::detail
-
-#if defined(_MSC_VER)
-#pragma warning(pop) // Restore warnings to previous state.
-#endif
-
-#endif
diff --git a/boost/uuid/entropy_error.hpp b/boost/uuid/entropy_error.hpp
new file mode 100644
index 0000000000..27f2936e5e
--- /dev/null
+++ b/boost/uuid/entropy_error.hpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2017 James E. King III
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENCE_1_0.txt)
+//
+// Entropy error class
+//
+
+#ifndef BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP
+#define BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP
+
+#include <boost/cstdint.hpp>
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace uuids {
+
+//! \brief Given boost::system::system_error is in a module that
+//! is not header-only, we define our own exception type
+//! to handle entropy provider errors instead,
+class entropy_error : public std::runtime_error
+{
+public:
+ entropy_error(boost::intmax_t errCode, const std::string& message)
+ : std::runtime_error(message)
+ , m_errcode(errCode)
+ {
+ }
+
+ virtual boost::intmax_t errcode() const
+ {
+ return m_errcode;
+ }
+
+private:
+ boost::intmax_t m_errcode;
+};
+
+} // uuids
+} // boost
+
+#endif // BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP
diff --git a/boost/uuid/name_generator.hpp b/boost/uuid/name_generator.hpp
index dbd1001b8c..ead8174d1c 100644
--- a/boost/uuid/name_generator.hpp
+++ b/boost/uuid/name_generator.hpp
@@ -1,7 +1,7 @@
// Boost name_generator.hpp header file -----------------------------//
// Copyright 2010 Andy Tompkins.
-// Copyright 2017 James E. King, III
+// Copyright 2017 James E. King III
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
diff --git a/boost/uuid/name_generator_md5.hpp b/boost/uuid/name_generator_md5.hpp
index f167584c41..7b13698df2 100644
--- a/boost/uuid/name_generator_md5.hpp
+++ b/boost/uuid/name_generator_md5.hpp
@@ -1,6 +1,6 @@
// Boost name_generator_md5.hpp header file ------------------------//
-// Copyright 2017 James E. King, III
+// Copyright 2017 James E. King III
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
diff --git a/boost/uuid/name_generator_sha1.hpp b/boost/uuid/name_generator_sha1.hpp
index 849c75fd02..c34425f5b0 100644
--- a/boost/uuid/name_generator_sha1.hpp
+++ b/boost/uuid/name_generator_sha1.hpp
@@ -1,7 +1,7 @@
// Boost name_generator_sha1.hpp header file ------------------------//
// Copyright 2010 Andy Tompkins.
-// Copyright 2017 James E. King, III
+// Copyright 2017 James E. King III
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
diff --git a/boost/uuid/random_generator.hpp b/boost/uuid/random_generator.hpp
index a635ef03f7..c84fc5472c 100644
--- a/boost/uuid/random_generator.hpp
+++ b/boost/uuid/random_generator.hpp
@@ -1,6 +1,7 @@
// Boost random_generator.hpp header file ----------------------------------------------//
// Copyright 2010 Andy Tompkins.
+// Copyright 2017 James E. King III
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -8,20 +9,43 @@
#ifndef BOOST_UUID_RANDOM_GENERATOR_HPP
#define BOOST_UUID_RANDOM_GENERATOR_HPP
-#include <boost/uuid/uuid.hpp>
-#include <boost/uuid/detail/seed_rng.hpp>
+#include <boost/assert.hpp>
+#include <boost/core/enable_if.hpp>
+#include <boost/core/null_deleter.hpp>
+#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/core/null_deleter.hpp>
-#include <boost/assert.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/tti/has_member_function.hpp>
+#include <boost/uuid/detail/random_provider.hpp>
+#include <boost/uuid/uuid.hpp>
#include <limits>
namespace boost {
namespace uuids {
-// generate a random-based uuid
+namespace detail {
+ template<class U>
+ U& set_uuid_random_vv(U& u)
+ {
+ // set variant
+ // must be 0b10xxxxxx
+ *(u.begin() + 8) &= 0xBF;
+ *(u.begin() + 8) |= 0x80;
+
+ // set version
+ // must be 0b0100xxxx
+ *(u.begin() + 6) &= 0x4F; //0b01001111
+ *(u.begin() + 6) |= 0x40; //0b01000000
+
+ return u;
+ }
+
+ BOOST_TTI_HAS_MEMBER_FUNCTION(seed)
+}
+
+//! generate a random-based uuid
+//! \param[in] UniformRandomNumberGenerator see Boost.Random documentation
template <typename UniformRandomNumberGenerator>
class basic_random_generator {
private:
@@ -31,7 +55,9 @@ private:
public:
typedef uuid result_type;
- // default constructor creates the random number generator
+ // default constructor creates the random number generator and
+ // if the UniformRandomNumberGenerator is a PseudoRandomNumberGenerator
+ // then it gets seeded by a random_provider.
basic_random_generator()
: pURNG(new UniformRandomNumberGenerator)
, generator
@@ -42,8 +68,8 @@ public:
)
)
{
- // seed the random number generator
- detail::seed(*pURNG);
+ // seed the random number generator if it is capable
+ seed(*pURNG);
}
// keep a reference to a random number generator
@@ -74,9 +100,9 @@ public:
BOOST_ASSERT(pURNG);
}
- uuid operator()()
+ result_type operator()()
{
- uuid u;
+ result_type u;
int i=0;
unsigned long random_value = generator();
@@ -90,26 +116,61 @@ public:
*it = static_cast<uuid::value_type>((random_value >> (i*8)) & 0xFF);
}
- // set variant
- // must be 0b10xxxxxx
- *(u.begin()+8) &= 0xBF;
- *(u.begin()+8) |= 0x80;
+ return detail::set_uuid_random_vv(u);
+ }
- // set version
- // must be 0b0100xxxx
- *(u.begin()+6) &= 0x4F; //0b01001111
- *(u.begin()+6) |= 0x40; //0b01000000
+private:
+ // Detect whether UniformRandomNumberGenerator has a seed() method which indicates that
+ // it is a PseudoRandomNumberGenerator and needs a seed to initialize it. This allows
+ // basic_random_generator to take any type of UniformRandomNumberGenerator and still
+ // meet the post-conditions for the default constructor.
+
+ template<class MaybePseudoRandomNumberGenerator>
+ typename boost::enable_if<detail::has_member_function_seed<MaybePseudoRandomNumberGenerator, void> >::type
+ seed(MaybePseudoRandomNumberGenerator& rng)
+ {
+ detail::random_provider seeder;
+ rng.seed(seeder);
+ }
- return u;
+ template<class MaybePseudoRandomNumberGenerator>
+ typename boost::disable_if<detail::has_member_function_seed<MaybePseudoRandomNumberGenerator, void> >::type
+ seed(MaybePseudoRandomNumberGenerator&)
+ {
}
-private:
shared_ptr<UniformRandomNumberGenerator> pURNG;
generator_type generator;
};
+//! \brief a far less complex random generator that uses
+//! operating system provided entropy which will
+//! satisfy the majority of use cases
+class random_generator_pure
+{
+public:
+ typedef uuid result_type;
+
+ //! \returns a random, valid uuid
+ //! \throws entropy_error
+ result_type operator()()
+ {
+ result_type result;
+ prov_.get_random_bytes(&result, sizeof(result_type));
+ return detail::set_uuid_random_vv(result);
+ }
+
+private:
+ detail::random_provider prov_;
+};
+
+#if defined(BOOST_UUID_RANDOM_GENERATOR_COMPAT)
typedef basic_random_generator<mt19937> random_generator;
+#else
+typedef random_generator_pure random_generator;
+typedef basic_random_generator<mt19937> random_generator_mt19937;
+#endif
}} // namespace boost::uuids
-#endif //BOOST_UUID_RANDOM_GENERATOR_HPP
+#endif // BOOST_UUID_RANDOM_GENERATOR_HPP
diff --git a/boost/uuid/seed_rng.hpp b/boost/uuid/seed_rng.hpp
deleted file mode 100644
index 5f603110cb..0000000000
--- a/boost/uuid/seed_rng.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE_1_0.txt or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
-
-#ifndef BOOST_UUID_SEED_RNG_DEPRECATED_HPP
-#define BOOST_UUID_SEED_RNG_DEPRECATED_HPP
-
-#include <boost/uuid/detail/seed_rng.hpp>
-
-#if defined(__GNUC__) || defined(_MSC_VER)
-#pragma message("This header is implementation detail and provided for backwards compatibility.")
-#endif
-
-#endif // BOOST_UUID_SEED_RNG_DEPRECATED_HPP