Hi,

On Linux, reading from /dev/[u]random can fail with an EINTR or EAGAIN
error. In that case, one should just retry. No sleep is required.
If this error occured on the blocking class, an error was thrown which
is not correct. Also the blocking case had some issues.
Attached you find a patch that solves this.

Note: this solution makes the non-blocking code _somewhat_ blocking. To
solve this, the get-routine for the non-blocking should return a boolean
indicatin data was available or not. Because in theory, read might also
return 0.

diff -uNrBbd cr.org/osrng.cpp cr.new/osrng.cpp
--- cr.org/osrng.cpp    2010-08-06 18:44:30.000000000 +0200
+++ cr.new/osrng.cpp    2012-10-17 17:22:01.151537879 +0200
@@ -83,8 +83,22 @@
        if (!CryptGenRandom(m_Provider.GetProviderHandle(), (DWORD)size, 
output))
                throw OS_RNG_Err("CryptGenRandom");
 #else
-       if (read(m_fd, output, size) != size)
+       while(size)
+       {
+               int rc = read(m_fd, output, size);
+
+               if (rc == -1)
+               {
+                       // /dev/urandom reads CAN give EAGAIN errors! (maybe 
EINTR as well)
+                       if (errno != EINTR && errno != EAGAIN)
                throw OS_RNG_Err("read /dev/urandom");
+
+                       continue;
+               }
+
+               output += rc;
+               size -= rc;
+       }
 #endif
 }
 
@@ -119,10 +133,17 @@
        while (size)
        {
                // on some systems /dev/random will block until all bytes
-               // are available, on others it will returns immediately
+               // are available, on others it returns immediately
                ssize_t len = read(m_fd, output, size);
                if (len < 0)
+               {
+                       // /dev/random reads CAN give EAGAIN errors! (maybe 
EINTR as well)
+                       if (errno != EINTR && errno != EAGAIN)
                        throw OS_RNG_Err("read " 
CRYPTOPP_BLOCKING_RNG_FILENAME);
+
+                       continue;
+               }
+
                size -= len;
                output += len;
                if (size)


Folkert van Heusden

-- 
Looking for a cheap but fast webhoster with an excellent helpdesk?
http://keetweej.vanheusden.com/redir.php?id=1001
----------------------------------------------------------------------
Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com

-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.

Reply via email to