Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:31

0001 //
0002 // Copyright (c) 2017 James E. King III
0003 //
0004 // Distributed under the Boost Software License, Version 1.0.
0005 // (See accompanying file LICENSE_1_0.txt or copy at
0006 //   https://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // BCrypt provider for entropy
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     //! Obtain entropy and place it into a memory location
0075     //! \param[in]  buf  the location to write entropy
0076     //! \param[in]  siz  the number of bytes to acquire
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 } // detail
0106 } // uuids
0107 } // boost