address review comments on osrandom engine, reorganize some code
diff --git a/cryptography/hazmat/bindings/openssl/osrand_engine.py b/cryptography/hazmat/bindings/openssl/osrand_engine.py
index bca2d79..a04daed 100644
--- a/cryptography/hazmat/bindings/openssl/osrand_engine.py
+++ b/cryptography/hazmat/bindings/openssl/osrand_engine.py
@@ -32,67 +32,7 @@
 MACROS = """
 """
 
-CUSTOMIZATIONS = """
-static const char *Cryptography_osrandom_engine_id= "osrandom";
-static const char *Cryptography_osrandom_engine_name = "osrandom_engine";
-
-#ifndef _WIN32
-static int urandom_fd = -1;
-
-static int osrandom_rand_bytes(unsigned char *buffer, int size) {
-    ssize_t n;
-    while (0 < size) {
-        do {
-            n = read(urandom_fd, buffer, (size_t)size);
-        } while (n < 0 && errno == EINTR);
-        if (n <= 0) {
-            return 0;
-        }
-        buffer += n;
-        size -= n;
-    }
-    return 1;
-}
-
-static int osrandom_rand_status(void) {
-    if (urandom_fd == -1) {
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-static int osrandom_init(ENGINE *e) {
-    if (urandom_fd > -1) {
-        return 1;
-    }
-    urandom_fd = open("/dev/urandom", O_RDONLY);
-    if (urandom_fd > -1) {
-        if (fcntl(urandom_fd, F_SETFD, FD_CLOEXEC) == -1) {
-            return 0;
-        }
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-static int osrandom_finish(ENGINE *e) {
-    int n;
-    do {
-        n = close(urandom_fd);
-    } while (n < 0 && errno == EINTR);
-    if (n < 0) {
-        urandom_fd = -1;
-        return 0;
-    } else {
-        urandom_fd = -1;
-        return 1;
-    }
-}
-#endif
-
-#ifdef _WIN32
+WIN32_CUSTOMIZATIONS = """
 static HCRYPTPROV hCryptProv = 0;
 
 static int osrandom_init(ENGINE *e) {
@@ -117,6 +57,7 @@
     while (size > 0) {
         chunk = size;
         if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer)) {
+            ERR_put_error(ERR_LIB_RAND, 0, ERR_R_RAND_LIB, "osrandom.py", 0);
             return 0;
         }
         buffer += chunk;
@@ -141,14 +82,91 @@
         return 1;
     }
 }
-#endif /* MS_WINDOWS */
+"""
+
+POSIX_CUSTOMIZATIONS = """
+static int urandom_fd = -1;
+
+static int osrandom_init(ENGINE *e) {
+    if (urandom_fd > -1) {
+        return 1;
+    }
+    urandom_fd = open("/dev/urandom", O_RDONLY);
+    if (urandom_fd > -1) {
+        if (fcntl(urandom_fd, F_SETFD, FD_CLOEXEC) == -1) {
+            return 0;
+        }
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static int osrandom_rand_bytes(unsigned char *buffer, int size) {
+    ssize_t n;
+    while (size > 0) {
+        do {
+            n = read(urandom_fd, buffer, (size_t)size);
+        } while (n < 0 && errno == EINTR);
+        if (n <= 0) {
+            ERR_put_error(ERR_LIB_RAND, 0, ERR_R_RAND_LIB, "osrandom.py", 0);
+            return 0;
+        }
+        buffer += n;
+        size -= n;
+    }
+    return 1;
+}
+
+static int osrandom_finish(ENGINE *e) {
+    int n;
+    do {
+        n = close(urandom_fd);
+    } while (n < 0 && errno == EINTR);
+    urandom_fd = -1;
+    if (n < 0) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+static int osrandom_rand_status(void) {
+    if (urandom_fd == -1) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+"""
+
+CUSTOMIZATIONS = """
+static const char *Cryptography_osrandom_engine_id = "osrandom";
+static const char *Cryptography_osrandom_engine_name = "osrandom_engine";
+
+#if defined(_WIN32)
+""" + WIN32_CUSTOMIZATIONS + """
+#else
+""" + POSIX_CUSTOMIZATIONS + """
+#endif
+
+/* This replicates the behavior of the OpenSSL FIPS RNG, which returns a
+-1 in the event that there is an error when calling RAND_pseudo_bytes.  */
+static int osrandom_pseudo_rand_bytes(unsigned char *buffer, int size) {
+    int res = osrandom_rand_bytes(buffer, size);
+    if (res == 0) {
+        return -1;
+    } else {
+        return res;
+    }
+}
 
 static RAND_METHOD osrandom_rand = {
     NULL,
     osrandom_rand_bytes,
     NULL,
     NULL,
-    osrandom_rand_bytes,
+    osrandom_pseudo_rand_bytes,
     osrandom_rand_status,
 };
 
@@ -162,6 +180,7 @@
             !ENGINE_set_RAND(e, &osrandom_rand) ||
             !ENGINE_set_init_function(e, osrandom_init) ||
             !ENGINE_set_finish_function(e, osrandom_finish)) {
+        ENGINE_free(e);
         return 0;
     }
     if (!ENGINE_add(e)) {
diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst
index 8eb02ea..79c5885 100644
--- a/docs/hazmat/backends/openssl.rst
+++ b/docs/hazmat/backends/openssl.rst
@@ -55,7 +55,7 @@
 On Windows ``CryptGenRandom`` is backed by `Fortuna`_.
 
 Linux uses its own PRNG design. ``/dev/urandom`` is a non-blocking source seeded
-from the ``/dev/random`` pool.
+from the same pool as ``/dev/random``.
 
 
 .. _`OpenSSL`: https://www.openssl.org/