security: Generate random block in Tpm.

Change-Id: Ia65d32802ed0ebc76605ae7975ea02f4c2db737d
diff --git a/src/security/sec-tpm-file.cpp b/src/security/sec-tpm-file.cpp
index 52f14ba..47cf83b 100644
--- a/src/security/sec-tpm-file.cpp
+++ b/src/security/sec-tpm-file.cpp
@@ -35,7 +35,7 @@
 
 class SecTpmFile::Impl {
 public:
-  Impl(const string &dir)
+  Impl(const string& dir)
   {
     if(dir.empty())
       m_keystorePath = boost::filesystem::path(getenv("HOME")) / ".ndnx" / "ndnsec-tpm-file";
@@ -49,8 +49,9 @@
   boost::filesystem::path m_keystorePath;
 };
 
+
 SecTpmFile::SecTpmFile(const string & dir)
-  : impl_(new Impl(dir))
+  : m_impl(new Impl(dir))
 {}
 
 void
@@ -70,7 +71,9 @@
     switch(keyType){
     case KEY_TYPE_RSA:
       {
-	AutoSeededRandomPool rng;
+        using namespace CryptoPP;
+        AutoSeededRandomPool rng;
+
 	InvertibleRSAFunction privateKey;
 	privateKey.Initialize(rng, keySize);
 	
@@ -139,8 +142,9 @@
     throw Error("private key doesn't exists");
  
   try{
+    using namespace CryptoPP;
     AutoSeededRandomPool rng;
-      
+
     //Read private key
     ByteQueue bytes;
     string privateKeyFileName = nameTransform(keyURI, ".pri");
@@ -180,8 +184,9 @@
 	throw Error("private key doesn't exist");
 
       try{
-	AutoSeededRandomPool rng;
-	
+	using namespace CryptoPP;
+        AutoSeededRandomPool rng;
+
 	//Read private key
 	ByteQueue bytes;
 	string privateKeyFileName = nameTransform(keyURI, ".pri");
@@ -241,7 +246,8 @@
 	throw Error("public key doesn't exist");
       try
 	{
-	  AutoSeededRandomPool rng;
+          using namespace CryptoPP;
+          AutoSeededRandomPool rng;
 
 	  //Read private key
 	  ByteQueue bytes;
@@ -307,9 +313,11 @@
     switch(keyType){
     case KEY_TYPE_AES:
       {
-	AutoSeededRandomPool rnd;
+        using namespace CryptoPP;
+        AutoSeededRandomPool rng;
+
 	SecByteBlock key(0x00, keySize);
-	rnd.GenerateBlock(key, keySize );
+	rng.GenerateBlock(key, keySize);
 	
 	StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
 	
@@ -376,18 +384,30 @@
         }
     }
 
-  return (impl_->m_keystorePath / (digest + extension)).string();
+  return (m_impl->m_keystorePath / (digest + extension)).string();
 }
 
 void 
 SecTpmFile::maintainMapping(string str1, string str2)
 {
   std::ofstream outfile;
-  string dirFile = (impl_->m_keystorePath / "mapping.txt").string();
+  string dirFile = (m_impl->m_keystorePath / "mapping.txt").string();
 
   outfile.open(dirFile.c_str(), std::ios_base::app);
   outfile << str1 << ' ' << str2 << '\n';
   outfile.close();
 }
 
+bool
+SecTpmFile::generateRandomBlock(uint8_t* res, size_t size)
+{
+  try{
+    CryptoPP::AutoSeededRandomPool rng;
+    rng.GenerateBlock(res, size);
+    return true;
+  }catch(const CryptoPP::Exception& e){
+    return false;
+  }
+}
+
 } //ndn
diff --git a/src/security/sec-tpm-file.hpp b/src/security/sec-tpm-file.hpp
index d0a68b8..7a92ec1 100644
--- a/src/security/sec-tpm-file.hpp
+++ b/src/security/sec-tpm-file.hpp
@@ -108,6 +108,8 @@
 
   std::string
   nameTransform(const std::string &keyName, const std::string &extension);
+  virtual bool
+  generateRandomBlock(uint8_t* res, size_t size);
 
 private:
   void 
@@ -115,8 +117,9 @@
   
 private:
   class Impl;
-  std::auto_ptr<Impl> impl_;
+  shared_ptr<Impl> m_impl;
 };
+
 }//ndn
 
 #endif
diff --git a/src/security/sec-tpm-memory.cpp b/src/security/sec-tpm-memory.cpp
index a72e385..a115d48 100644
--- a/src/security/sec-tpm-memory.cpp
+++ b/src/security/sec-tpm-memory.cpp
@@ -13,6 +13,7 @@
 #include <openssl/ssl.h>
 #include <openssl/sha.h>
 #include <openssl/rsa.h>
+#include <cryptopp/osrng.h>
 
 using namespace std;
 
@@ -154,4 +155,16 @@
     return false;
 }
 
+bool
+SecTpmMemory::generateRandomBlock(uint8_t* res, size_t size)
+{
+  try{
+    CryptoPP::AutoSeededRandomPool rng;
+    rng.GenerateBlock(res, size);
+    return true;
+  }catch(const CryptoPP::Exception& e){
+    return false;
+  }
+}
+
 }
diff --git a/src/security/sec-tpm-memory.hpp b/src/security/sec-tpm-memory.hpp
index 38bc5ff..69f5052 100644
--- a/src/security/sec-tpm-memory.hpp
+++ b/src/security/sec-tpm-memory.hpp
@@ -107,6 +107,9 @@
   virtual void 
   generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);
 
+  virtual bool
+  generateRandomBlock(uint8_t* res, size_t size);
+
   /**
    * Check if a particular key exists.
    * @param keyName The name of the key.
diff --git a/src/security/sec-tpm-osx.cpp b/src/security/sec-tpm-osx.cpp
index 27039bf..3f14f43 100644
--- a/src/security/sec-tpm-osx.cpp
+++ b/src/security/sec-tpm-osx.cpp
@@ -19,6 +19,7 @@
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <Security/Security.h>
+#include <Security/SecRandom.h>
 #include <CoreServices/CoreServices.h>
 
 using namespace std;
@@ -562,6 +563,11 @@
 
 }
 
+bool
+SecTpmOsx::generateRandomBlock(uint8_t* res, size_t size)
+{
+  return (SecRandomCopyBytes(kSecRandomDefault, size, res) == 0);
+}
 
 ////////////////////////////////
 // OSXPrivateKeyStorage::Impl //
diff --git a/src/security/sec-tpm-osx.hpp b/src/security/sec-tpm-osx.hpp
index 1f95cdc..c4a4972 100644
--- a/src/security/sec-tpm-osx.hpp
+++ b/src/security/sec-tpm-osx.hpp
@@ -86,7 +86,10 @@
    * @return True if the key exists, otherwise false.
    */
   virtual bool
-  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);  
+  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass); 
+
+  virtual bool
+  generateRandomBlock(uint8_t* res, size_t size); 
 
 
   ////////////////////////////////////////////////////////////////////////////////////
@@ -117,7 +120,7 @@
 
  private:
   class Impl;
-  std::auto_ptr<Impl> m_impl;
+  shared_ptr<Impl> m_impl;
 };
   
 } // namespace ndn
diff --git a/src/security/sec-tpm.hpp b/src/security/sec-tpm.hpp
index ec3334d..9c15ad7 100644
--- a/src/security/sec-tpm.hpp
+++ b/src/security/sec-tpm.hpp
@@ -102,6 +102,16 @@
    */
   virtual bool
   doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) = 0;  
+
+  /**
+   * @brief Generate a random number.
+   * 
+   * @param res The pointer to the generated number.
+   * @param size The random number size.
+   * @return true for success, otherwise false.
+   */
+  virtual bool
+  generateRandomBlock(uint8_t* res, size_t size) = 0;
 };
 
 }
diff --git a/tests/security/test-sec-tpm-file.cpp b/tests/security/test-sec-tpm-file.cpp
index 51ecbe2..55bc983 100644
--- a/tests/security/test-sec-tpm-file.cpp
+++ b/tests/security/test-sec-tpm-file.cpp
@@ -65,6 +65,26 @@
   tpm.deleteKeyPairInTpm(keyName);
 }
 
+BOOST_AUTO_TEST_CASE (RandomGenerator)
+{
+  SecTpmFile tpm;
+
+  size_t scale = 1000;
+  size_t size = 256 * scale;
+  uint8_t* block = new uint8_t[size];
+  tpm.generateRandomBlock(block, size);
+
+  map<uint8_t, int> counter;
+  for(size_t i = 0; i < size; i++)
+    counter[block[i]] += 1;
+
+  float dev = 0.0;
+  for(size_t i = 0; i != 255; i++)
+    dev += ((counter[i] - scale) * (counter[i] - scale)) * 1.0 / (scale * scale);
+
+  BOOST_CHECK_CLOSE(dev / 256, 0.001, 100);
+
+}
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace ndn
diff --git a/tests/security/test-sec-tpm-osx.cpp b/tests/security/test-sec-tpm-osx.cpp
index 5bd0467..a0a3bb9 100644
--- a/tests/security/test-sec-tpm-osx.cpp
+++ b/tests/security/test-sec-tpm-osx.cpp
@@ -65,6 +65,26 @@
   tpm.deleteKeyPairInTpm(keyName);
 }
 
+BOOST_AUTO_TEST_CASE (RandomGenerator)
+{
+  SecTpmOsx tpm;
+
+  size_t scale = 1000;
+  size_t size = 256 * scale;
+  uint8_t* block = new uint8_t[size];
+  tpm.generateRandomBlock(block, size);
+
+  map<uint8_t, int> counter;
+  for(size_t i = 0; i < size; i++)
+    counter[block[i]] += 1;
+
+  float dev = 0.0;
+  for(size_t i = 0; i != 255; i++)
+    dev += ((counter[i] - scale) * (counter[i] - scale)) * 1.0 / (scale * scale);
+
+  BOOST_CHECK_CLOSE(dev / 256, 0.001, 100);
+
+}
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace ndn