I received this error after porting part of crypto++ 5.1 to Solaris.

This was the error:
OS_Rng: read /dev/urandom operation failed with error 0

This is the machine ID:
% uname -a
SunOS set 5.8 Generic_108528-21 sun4u sparc SUNW,UltraSPARC-IIi-Engine

The following function replacement in osrng.cpp resolved the problem:

************************************************************
void NonblockingRng::GenerateBlock(byte *output, unsigned int size)
{
#ifdef CRYPTOPP_WIN32_AVAILABLE
#       ifdef WORKAROUND_MS_BUG_Q258000
                static MicrosoftCryptoProvider m_Provider;
#       endif
        if (!CryptGenRandom(m_Provider.GetProviderHandle(), size, output))
                throw OS_RNG_Err("CryptGenRandom");
#else
        unsigned int    n_total = 0;
        int                             n_read;

        while (n_total != size)
        {
                if ((n_read = read(m_fd, output, size - n_total)) <= 0)
                {
                        std::string             s_mesg = "read /dev/urandom ";

                        s_mesg += "(req=" + IntToString(size - n_total);
                        s_mesg += ",ret=" + IntToString(n_read) + ")";
                        throw OS_RNG_Err(s_mesg);
                }
                n_total += n_read;
        }
#endif
}
************************************************************

I've included a patch file after the end of this post.

-- 
Russell Robinson (mailto:[EMAIL PROTECTED])
Author of Tectite (CRM and Licensing for Software Developers)
Download your free CRM from: http://www.tectite.com/


--- old/osrng.cpp       Wed Jul 28 10:48:08 2004
+++ osrng.cpp   Wed Jul 28 10:45:02 2004
@@ -87,8 +87,21 @@
        if (!CryptGenRandom(m_Provider.GetProviderHandle(), size, output))
                throw OS_RNG_Err("CryptGenRandom");
 #else
-       if (read(m_fd, output, size) != size)
-               throw OS_RNG_Err("read /dev/urandom");
+       unsigned int    n_total = 0;
+       int                             n_read;
+
+       while (n_total != size)
+       {
+               if ((n_read = read(m_fd, output, size - n_total)) <= 0)
+               {
+                       std::string             s_mesg = "read /dev/urandom ";
+
+                       s_mesg += "(req=" + IntToString(size - n_total);
+                       s_mesg += ",ret=" + IntToString(n_read) + ")";
+                       throw OS_RNG_Err(s_mesg);
+               }
+               n_total += n_read;
+       }
 #endif
 }


Reply via email to