// bdlb_randomdevice.h -*-C++-*- #ifndef INCLUDED_BDLB_RANDOMDEVICE #define INCLUDED_BDLB_RANDOMDEVICE #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a common interface to a system's random number generator. // //@CLASSES: // bdlb::RandomDevice: namespace for system specific random-number generators. // //@SEE_ALSO: // //@DESCRIPTION: This component provides a namespace, 'bdlb::RandomDevice', for // a suite of functions used to generate random seeds from platform-dependent // random number generators. Two variants are provided: one which may block, // but which potentially samples from a stronger distribution, and another // which does not block, but which potentially should not be used for // cryptography. The strength of these random numbers and the performance of // these calls is strongly dependent on the underlying system. On UNIX-like // platforms 'getRandomBytes()' reads from '/dev/random' and // 'getRandomBytesNonBlocking()' reads from '/dev/urandom'. On Windows both // methods use 'CryptGenRandom'. // // Note that (at least on UNIX-like systems) it is not appropriate to call // these functions repeatedly to generate many random numbers. A call to // 'getRandomBytes()' can block if available entropy is exhausted, and both // 'getRandomBytes()' and 'getRandomBytesNonBlocking()' open and close their // respective devices on each call. Instead, these functions should be used // for seeding pseudo-random random number generators. (E.g., promiscuous use // of 'getRandomBytes()' appears to have caused the WP in '{DRQS 92851043}'.) // // There is discussion about which of '/dev/random' or '/dev/urandom' is best, // especially on modern Linux systems, while 'man' pages on other UNIX systems // continue to make claims about '/dev/random' providing "more secure" numbers // than '/dev/urandom'. See '{http://www.2uo.de/myths-about-urandom/}', for // example. This component deliberately takes no stand on the issue, making // both available and leaving it for users to decide which to use. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Seeding the Random-Number Generator /// - - - - - - - - - - - - - - - - - - - - - - - // System-provided random-number generators generally must be initialized with // a seed value from which they go on to produce their stream of pseudo-random // numbers. We can use 'RandomDevice' to provide such a seed. // // First, we obtain the results of invoking the random-number generator without // having seeded it: //.. // int unseededR1 = rand(); // int unseededR2 = rand(); //.. // Then, we obtain a random number: //.. // int seed = 0; // int status = bdlb::RandomDevice::getRandomBytes( // reinterpret_cast<unsigned char *>(&seed), sizeof(seed)); // assert(0 == status); // assert(0 != seed); // This will fail every few billion attempts... //.. // Next, we seed the random-number generator with our seed: //.. // srand(seed); //.. // Finally, we observe that we obtain different numbers: //.. // assert(unseededR1 != rand()); // assert(unseededR2 != rand()); //.. #include <bdlscm_version.h> #include <bsls_types.h> namespace BloombergLP { namespace bdlb { // =================== // struct RandomDevice // =================== struct RandomDevice { // This 'struct' provides a namespace for a suite of functions used for // acquiring random numbers from the system. // TYPES typedef bsls::Types::size_type size_t; // for brevity of name // CLASS METHODS static int getRandomBytes(unsigned char *buffer, size_t numBytes); // Read the specified 'numBytes' from the system random number // generator into the specified 'buffer'. Returns 0 on success, // non-zero otherwise. Note that this method may block if called // repeatedly or if 'numBytes' is high. static int getRandomBytesNonBlocking(unsigned char *buffer, size_t numBytes); // Read the specified 'numBytes' from the system non-blocking random // number generator into the specified 'buffer'. Returns 0 on success, // non-zero otherwise. Note that the cryptographic strength of samples // drawn from this pool may or may not be lower than that of those // drawn from the blocking pool, and may vary by platform. }; } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2014 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------