File indexing completed on 2025-01-18 09:53:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <cstddef>
0012 #include <boost/config.hpp>
0013 #include <boost/core/ignore_unused.hpp>
0014 #include <boost/move/core.hpp>
0015 #include <boost/numeric/conversion/cast.hpp>
0016 #include <boost/winapi/bcrypt.hpp>
0017 #include <boost/winapi/get_last_error.hpp>
0018 #include <boost/throw_exception.hpp>
0019
0020 #if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB))
0021 # define BOOST_LIB_NAME "bcrypt"
0022 # if defined(BOOST_AUTO_LINK_NOMANGLE)
0023 # include <boost/config/auto_link.hpp>
0024 # else
0025 # define BOOST_AUTO_LINK_NOMANGLE
0026 # include <boost/config/auto_link.hpp>
0027 # undef BOOST_AUTO_LINK_NOMANGLE
0028 # endif
0029 #endif
0030
0031 namespace boost {
0032 namespace uuids {
0033 namespace detail {
0034
0035 class random_provider_base
0036 {
0037 BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
0038
0039 public:
0040 random_provider_base()
0041 : hProv_(NULL)
0042 {
0043 boost::winapi::NTSTATUS_ status =
0044 boost::winapi::BCryptOpenAlgorithmProvider(
0045 &hProv_,
0046 boost::winapi::BCRYPT_RNG_ALGORITHM_,
0047 NULL,
0048 0);
0049
0050 if (BOOST_UNLIKELY(status != 0))
0051 {
0052 BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptOpenAlgorithmProvider"));
0053 }
0054 }
0055
0056 random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : hProv_(that.hProv_)
0057 {
0058 that.hProv_ = NULL;
0059 }
0060
0061 random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
0062 {
0063 destroy();
0064 hProv_ = that.hProv_;
0065 that.hProv_ = NULL;
0066 return *this;
0067 }
0068
0069 ~random_provider_base() BOOST_NOEXCEPT
0070 {
0071 destroy();
0072 }
0073
0074
0075
0076
0077 void get_random_bytes(void *buf, std::size_t siz)
0078 {
0079 boost::winapi::NTSTATUS_ status =
0080 boost::winapi::BCryptGenRandom(
0081 hProv_,
0082 static_cast<boost::winapi::PUCHAR_>(buf),
0083 boost::numeric_cast<boost::winapi::ULONG_>(siz),
0084 0);
0085
0086 if (BOOST_UNLIKELY(status != 0))
0087 {
0088 BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptGenRandom"));
0089 }
0090 }
0091
0092 private:
0093 void destroy() BOOST_NOEXCEPT
0094 {
0095 if (hProv_)
0096 {
0097 boost::ignore_unused(boost::winapi::BCryptCloseAlgorithmProvider(hProv_, 0));
0098 }
0099 }
0100
0101 private:
0102 boost::winapi::BCRYPT_ALG_HANDLE_ hProv_;
0103 };
0104
0105 }
0106 }
0107 }