]> git.saurik.com Git - apple/security.git/blobdiff - cdsa/cdsa_utilities/devrandom.cpp
Security-177.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / devrandom.cpp
index 574a7142b8ad22f67a4faa99fc6fe4515642808f..05b180a0374a33f0c5a5b7fd17eb00857c015562 100644 (file)
 // devrandom - RNG operations based on /dev/random
 //
 #include <Security/devrandom.h>
+#include <Security/logging.h>
+
+using namespace UnixPlusPlus;
 
 
 namespace Security {
 
 
 //
-// DevRandomGenerator objects immediately open their file descriptors
+// The common (shared) open file descriptor to /dev/random
+//
+ModuleNexus<DevRandomGenerator::Readonly> DevRandomGenerator::mReader;
+ModuleNexus<DevRandomGenerator::Writable> DevRandomGenerator::mWriter;
+
+
+//
+// In the current implementation, opening the file descriptor is deferred.
 //
 DevRandomGenerator::DevRandomGenerator(bool writable)
 {
-    mDevRandom.open("/dev/random", writable ? O_RDWR : O_RDONLY);
 }
 
 
@@ -39,7 +48,18 @@ DevRandomGenerator::DevRandomGenerator(bool writable)
 //
 void DevRandomGenerator::random(void *data, size_t length)
 {
-    mDevRandom.read(data, length);
+    try {
+               size_t bytesRead = mReader().read(data, length);
+               if (bytesRead != length) {      // short read (shouldn't happen)
+                       Syslog::error("DevRandomGenerator: wanted %ld got %ld bytes",
+                               length, bytesRead);
+                       UnixError::throwMe(EIO);
+               }
+       } catch(const UnixError &uerr) {
+               Syslog::error("DevRandomGenerator: error %d reading /dev/random",
+                       uerr.error);
+               throw;
+       }
 }
 
 
@@ -48,7 +68,8 @@ void DevRandomGenerator::random(void *data, size_t length)
 //
 void DevRandomGenerator::addEntropy(const void *data, size_t length)
 {
-    mDevRandom.write(data, length);
+    if (mWriter().write(data, length) != length)
+               UnixError::throwMe(EIO);        // short write (shouldn't happen)
 }