security: Add KeyParams to support multiple types of keys.

Different types of keys may require different size options and default key size.
This commit also fixes the undefined behavior when processing the password of TPM.

Change-Id: I8fb95f28468be8299002f0d5146a4496ea1da25f
Refs: #1660
Refs: #1693
diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
index 22a25b3..a04e58b 100644
--- a/src/security/key-chain.cpp
+++ b/src/security/key-chain.cpp
@@ -38,6 +38,8 @@
 // Use a GUID as a magic number of KeyChain::DEFAULT_PREFIX identifier
 const Name KeyChain::DEFAULT_PREFIX("/723821fd-f534-44b3-80d9-44bf5f58bbbb");
 
+const RsaKeyParams KeyChain::DEFAULT_KEY_PARAMS;
+
 KeyChain::KeyChain()
   : m_pib(0)
   , m_tpm(0)
@@ -120,6 +122,49 @@
     throw Error("TPM type '" + tpmName + "' is not supported");
 }
 
+Name
+KeyChain::createIdentity(const Name& identityName, const KeyParams& params)
+{
+  m_pib->addIdentity(identityName);
+
+  Name keyName;
+  try
+    {
+      keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      keyName = generateKeyPair(identityName, true, params);
+      m_pib->setDefaultKeyNameForIdentity(keyName);
+    }
+
+  Name certName;
+  try
+    {
+      certName = m_pib->getDefaultCertificateNameForKey(keyName);
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
+      m_pib->addCertificateAsIdentityDefault(*selfCert);
+      certName = selfCert->getName();
+    }
+
+  return certName;
+}
+
+Name
+KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
+{
+  RsaKeyParams params(keySize);
+
+  Name keyName = generateKeyPair(identityName, isKsk, params);
+
+  m_pib->setDefaultKeyNameForIdentity(keyName);
+
+  return keyName;
+}
+
 shared_ptr<IdentityCertificate>
 KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
   const Name& signingIdentity,
@@ -199,6 +244,7 @@
 
   if (subjectDescription.empty())
     {
+      // OID 2.5.4.41 is the oid of subject name.
       CertificateSubjectDescription subjectName("2.5.4.41", keyName.getPrefix(-1).toUri());
       certificate->addSubjectDescription(subjectName);
     }
@@ -221,8 +267,8 @@
 KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
 {
   if (!m_pib->doesCertificateExist(certificateName))
-    throw SecPublicInfo::Error("Requested certificate ["
-                               + certificateName.toUri() + "] doesn't exist");
+    throw SecPublicInfo::Error("Requested certificate [" +
+                               certificateName.toUri() + "] doesn't exist");
 
   Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
 
@@ -269,7 +315,7 @@
 {
   Name keyName = IdentityCertificate::certificateNameToPublicKeyName(cert.getName());
   if (!m_tpm->doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
-    throw SecTpm::Error("private key does not exist!");
+    throw SecTpm::Error("Private key does not exist");
 
   SignatureSha256WithRsa signature;
   signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
@@ -282,7 +328,7 @@
 KeyChain::exportIdentity(const Name& identity, const std::string& passwordStr)
 {
   if (!m_pib->doesIdentityExist(identity))
-    throw SecPublicInfo::Error("Identity does not exist!");
+    throw SecPublicInfo::Error("Identity does not exist");
 
   Name keyName = m_pib->getDefaultKeyNameForIdentity(identity);
 
@@ -362,4 +408,146 @@
     }
 }
 
+Name
+KeyChain::generateKeyPair(const Name& identityName, bool isKsk, const KeyParams& params)
+{
+  Name keyName = m_pib->getNewKeyName(identityName, isKsk);
+
+  m_tpm->generateKeyPairInTpm(keyName.toUri(), params);
+
+  shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
+  m_pib->addKey(keyName, *pubKey);
+
+  return keyName;
+}
+
+void
+KeyChain::signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
+                            const Name& keyName, DigestAlgorithm digestAlgorithm)
+{
+  data.setSignature(signature);
+
+  EncodingBuffer encoder;
+  data.wireEncode(encoder, true);
+
+  Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(),
+                                          keyName, digestAlgorithm);
+  data.wireEncode(encoder, signatureValue);
+}
+
+void
+KeyChain::signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
+                            const Name& keyName, DigestAlgorithm digestAlgorithm)
+{
+  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
+  if (timestamp <= m_lastTimestamp)
+    {
+      timestamp = m_lastTimestamp + time::milliseconds(1);
+    }
+
+  Name signedName = interest.getName();
+  signedName
+    .append(name::Component::fromNumber(timestamp.count()))        // timestamp
+    .append(name::Component::fromNumber(random::generateWord64())) // nonce
+    .append(signature.getInfo());                                  // signatureInfo
+
+  Block sigValue = m_tpm->signInTpm(signedName.wireEncode().value(),
+                                    signedName.wireEncode().value_size(),
+                                    keyName,
+                                    digestAlgorithm);
+  sigValue.encode();
+  signedName.append(sigValue);                                     // signatureValue
+  interest.setName(signedName);
+}
+
+Signature
+KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
+{
+  Name signingCertificateName;
+  try
+    {
+      signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      signingCertificateName = createIdentity(identityName);
+      // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
+      // is a fatal error.
+    }
+
+  // We either get or create the signing certificate, sign data! (no exception unless fatal error
+  // in TPM)
+  return sign(buffer, bufferLength, signingCertificateName);
+}
+
+void
+KeyChain::signWithSha256(Data& data)
+{
+  DigestSha256 sig;
+  data.setSignature(sig);
+
+  Block sigValue(Tlv::SignatureValue,
+                 crypto::sha256(data.wireEncode().value(),
+                                data.wireEncode().value_size() -
+                                data.getSignature().getValue().size()));
+  data.setSignatureValue(sigValue);
+}
+
+void
+KeyChain::deleteCertificate(const Name& certificateName)
+{
+  try
+    {
+      if (m_pib->getDefaultCertificateName() == certificateName)
+        return;
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      // Not a real error, just try to delete the certificate
+    }
+
+  m_pib->deleteCertificateInfo(certificateName);
+}
+
+void
+KeyChain::deleteKey(const Name& keyName)
+{
+  try
+    {
+      if (m_pib->getDefaultKeyNameForIdentity(m_pib->getDefaultIdentity()) == keyName)
+        return;
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      // Not a real error, just try to delete the key
+    }
+
+  m_pib->deletePublicKeyInfo(keyName);
+  m_tpm->deleteKeyPairInTpm(keyName);
+}
+
+void
+KeyChain::deleteIdentity(const Name& identity)
+{
+  try
+    {
+      if (m_pib->getDefaultIdentity() == identity)
+        return;
+    }
+  catch (SecPublicInfo::Error& e)
+    {
+      // Not a real error, just try to delete the identity
+    }
+
+  std::vector<Name> nameList;
+  m_pib->getAllKeyNamesOfIdentity(identity, nameList, true);
+  m_pib->getAllKeyNamesOfIdentity(identity, nameList, false);
+
+  m_pib->deleteIdentityInfo(identity);
+
+  std::vector<Name>::const_iterator it = nameList.begin();
+  for(; it != nameList.end(); it++)
+    m_tpm->deleteKeyPairInTpm(*it);
+}
+
 }
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index 2b6da41..44ff1de 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -26,6 +26,7 @@
 
 #include "sec-public-info.hpp"
 #include "sec-tpm.hpp"
+#include "key-params.hpp"
 #include "secured-bag.hpp"
 #include "signature-sha256-with-rsa.hpp"
 #include "digest-sha256.hpp"
@@ -60,6 +61,9 @@
 
   static const Name DEFAULT_PREFIX;
 
+  // RsaKeyParams is set to be default for backward compatibility.
+  static const RsaKeyParams DEFAULT_KEY_PARAMS;
+
   KeyChain();
 
   template<class KeyChainTraits>
@@ -84,10 +88,11 @@
    *        self-signed certificate of the KSK.
    *
    * @param identityName The name of the identity.
+   * @param params The key parameter if a key needs to be generated for the identity.
    * @return The name of the default certificate of the identity.
    */
-  inline Name
-  createIdentity(const Name& identityName);
+  Name
+  createIdentity(const Name& identityName, const KeyParams& params = DEFAULT_KEY_PARAMS);
 
   /**
    * @brief Generate a pair of RSA keys for the specified identity.
@@ -109,7 +114,7 @@
    * @param keySize The size of the key.
    * @return The generated key name.
    */
-  inline Name
+  Name
   generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048);
 
   /**
@@ -217,13 +222,13 @@
    * @param identityName The identity name.
    * @return The Signature.
    */
-  inline Signature
+  Signature
   signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
 
   /**
    * @brief Set Sha256 weak signature for @param data
    */
-  inline void
+  void
   signWithSha256(Data& data);
 
   /**
@@ -252,7 +257,7 @@
    *
    * @param certificateName The certificate to be deleted.
    */
-  inline void
+  void
   deleteCertificate(const Name& certificateName);
 
   /**
@@ -263,7 +268,7 @@
    *
    * @param keyName The key to be deleted.
    */
-  inline void
+  void
   deleteKey(const Name& keyName);
 
   /**
@@ -274,7 +279,7 @@
    *
    * @param identity The identity to be deleted.
    */
-  inline void
+  void
   deleteIdentity(const Name& identity);
 
   /**
@@ -348,6 +353,12 @@
     return m_pib->addPublicKey(keyName, keyType, publicKeyDer);
   }
 
+  void
+  addKey(const Name& keyName, const PublicKey& publicKeyDer)
+  {
+    return m_pib->addKey(keyName, publicKeyDer);
+  }
+
   shared_ptr<PublicKey>
   getPublicKey(const Name& keyName) const
   {
@@ -547,9 +558,9 @@
   }
 
   void
-  generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
+  generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
   {
-    return m_tpm->generateKeyPairInTpm(keyName, keyType, keySize);
+    return m_tpm->generateKeyPairInTpm(keyName, params);
   }
 
   void
@@ -585,9 +596,9 @@
   }
 
   void
-  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
+  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
   {
-    return m_tpm->generateSymmetricKeyInTpm(keyName, keyType, keySize);
+    return m_tpm->generateSymmetricKeyInTpm(keyName, params);
   }
 
   bool
@@ -644,13 +655,12 @@
    *
    * @param identityName The name of the specified identity.
    * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
-   * @param keySize The size of the key pair.
+   * @param params The parameter of the key.
    * @return The name of the generated key.
    */
-  inline Name
+  Name
   generateKeyPair(const Name& identityName, bool isKsk = false,
-                  KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
+                  const KeyParams& params = DEFAULT_KEY_PARAMS);
 
   /**
    * @brief Sign the data using a particular key.
@@ -661,7 +671,7 @@
    * @param digestAlgorithm the digest algorithm.
    * @throws Tpm::Error
    */
-  inline void
+  void
   signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
                     const Name& keyName, DigestAlgorithm digestAlgorithm);
 
@@ -674,7 +684,7 @@
    * @param digestAlgorithm the digest algorithm.
    * @throws Tpm::Error
    */
-  inline void
+  void
   signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
                     const Name& keyName, DigestAlgorithm digestAlgorithm);
 
@@ -695,49 +705,10 @@
 }
 
 inline Name
-KeyChain::createIdentity(const Name& identityName)
-{
-  m_pib->addIdentity(identityName);
-
-  Name keyName;
-  try
-    {
-      keyName = m_pib->getDefaultKeyNameForIdentity(identityName);
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      keyName = generateRsaKeyPairAsDefault(identityName, true);
-    }
-
-  Name certName;
-  try
-    {
-      certName = m_pib->getDefaultCertificateNameForKey(keyName);
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
-      m_pib->addCertificateAsIdentityDefault(*selfCert);
-      certName = selfCert->getName();
-    }
-
-  return certName;
-}
-
-inline Name
 KeyChain::generateRsaKeyPair(const Name& identityName, bool isKsk, int keySize)
 {
-  return generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
-}
-
-inline Name
-KeyChain::generateRsaKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
-{
-  Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
-
-  m_pib->setDefaultKeyNameForIdentity(keyName);
-
-  return keyName;
+  RsaKeyParams params(keySize);
+  return generateKeyPair(identityName, isKsk, params);
 }
 
 template<typename T>
@@ -789,96 +760,6 @@
   sign(packet, signingCertificateName);
 }
 
-inline Signature
-KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
-{
-  Name signingCertificateName;
-  try
-    {
-      signingCertificateName = m_pib->getDefaultCertificateNameForIdentity(identityName);
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      signingCertificateName = createIdentity(identityName);
-      // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which
-      // is a fatal error.
-    }
-
-  // We either get or create the signing certificate, sign data! (no exception unless fatal error
-  // in TPM)
-  return sign(buffer, bufferLength, signingCertificateName);
-}
-
-inline void
-KeyChain::signWithSha256(Data& data)
-{
-  DigestSha256 sig;
-  data.setSignature(sig);
-
-  Block sigValue(Tlv::SignatureValue,
-                 crypto::sha256(data.wireEncode().value(),
-                                data.wireEncode().value_size() -
-                                data.getSignature().getValue().size()));
-  data.setSignatureValue(sigValue);
-}
-
-inline void
-KeyChain::deleteCertificate(const Name& certificateName)
-{
-  try
-    {
-      if (m_pib->getDefaultCertificateName() == certificateName)
-        return;
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      // Not a real error, just try to delete the certificate
-    }
-
-  m_pib->deleteCertificateInfo(certificateName);
-}
-
-inline void
-KeyChain::deleteKey(const Name& keyName)
-{
-  try
-    {
-      if (m_pib->getDefaultKeyNameForIdentity(m_pib->getDefaultIdentity()) == keyName)
-        return;
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      // Not a real error, just try to delete the key
-    }
-
-  m_pib->deletePublicKeyInfo(keyName);
-  m_tpm->deleteKeyPairInTpm(keyName);
-}
-
-inline void
-KeyChain::deleteIdentity(const Name& identity)
-{
-  try
-    {
-      if (m_pib->getDefaultIdentity() == identity)
-        return;
-    }
-  catch (SecPublicInfo::Error& e)
-    {
-      // Not a real error, just try to delete the identity
-    }
-
-  std::vector<Name> nameList;
-  m_pib->getAllKeyNamesOfIdentity(identity, nameList, true);
-  m_pib->getAllKeyNamesOfIdentity(identity, nameList, false);
-
-  m_pib->deleteIdentityInfo(identity);
-
-  std::vector<Name>::const_iterator it = nameList.begin();
-  for(; it != nameList.end(); it++)
-    m_tpm->deleteKeyPairInTpm(*it);
-}
-
 template<typename T>
 void
 KeyChain::sign(T& packet, const IdentityCertificate& certificate)
@@ -890,58 +771,6 @@
   signPacketWrapper(packet, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
 }
 
-inline Name
-KeyChain::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
-{
-  Name keyName = m_pib->getNewKeyName(identityName, isKsk);
-
-  m_tpm->generateKeyPairInTpm(keyName.toUri(), keyType, keySize);
-
-  shared_ptr<PublicKey> pubKey = m_tpm->getPublicKeyFromTpm(keyName.toUri());
-  m_pib->addPublicKey(keyName, keyType, *pubKey);
-
-  return keyName;
-}
-
-inline void
-KeyChain::signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature,
-                            const Name& keyName, DigestAlgorithm digestAlgorithm)
-{
-  data.setSignature(signature);
-
-  EncodingBuffer encoder;
-  data.wireEncode(encoder, true);
-
-  Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(),
-                                          keyName, digestAlgorithm);
-  data.wireEncode(encoder, signatureValue);
-}
-
-inline void
-KeyChain::signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature,
-                            const Name& keyName, DigestAlgorithm digestAlgorithm)
-{
-  time::milliseconds timestamp = time::toUnixTimestamp(time::system_clock::now());
-  if (timestamp <= m_lastTimestamp)
-    {
-      timestamp = m_lastTimestamp + time::milliseconds(1);
-    }
-
-  Name signedName = interest.getName();
-  signedName
-    .append(name::Component::fromNumber(timestamp.count()))        // timestamp
-    .append(name::Component::fromNumber(random::generateWord64())) // nonce
-    .append(signature.getInfo());                                  // signatureInfo
-
-  Block sigValue = m_tpm->signInTpm(signedName.wireEncode().value(),
-                                    signedName.wireEncode().value_size(),
-                                    keyName,
-                                    digestAlgorithm);
-  sigValue.encode();
-  signedName.append(sigValue);                                     // signatureValue
-  interest.setName(signedName);
-}
-
 }
 
 #endif // NDN_SECURITY_KEY_CHAIN_HPP
diff --git a/src/security/key-params.cpp b/src/security/key-params.cpp
new file mode 100644
index 0000000..7ee2e1e
--- /dev/null
+++ b/src/security/key-params.cpp
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "key-params.hpp"
+
+namespace ndn {
+
+static const uint32_t RSA_KEY_SIZES[] = {2048, 1024};
+static const uint32_t ECDSA_KEY_SIZES[] = {256, 384};
+static const uint32_t AES_KEY_SIZES[] = {64, 128, 256};
+
+uint32_t
+RsaKeyParamsInfo::checkKeySize(uint32_t size)
+{
+  for (size_t i = 0; i < (sizeof(RSA_KEY_SIZES) / sizeof(uint32_t)); i++)
+    {
+      if (RSA_KEY_SIZES[i] == size)
+        return size;
+    }
+  return getDefaultSize();
+}
+
+uint32_t
+RsaKeyParamsInfo::getDefaultSize()
+{
+  return RSA_KEY_SIZES[0];
+}
+
+uint32_t
+EcdsaKeyParamsInfo::checkKeySize(uint32_t size)
+{
+
+  for (size_t i = 0; i < (sizeof(ECDSA_KEY_SIZES) / sizeof(uint32_t)); i++)
+    {
+      if (ECDSA_KEY_SIZES[i] == size)
+        return size;
+    }
+  return getDefaultSize();
+}
+
+uint32_t
+EcdsaKeyParamsInfo::getDefaultSize()
+{
+  return ECDSA_KEY_SIZES[0];
+}
+
+
+uint32_t
+AesKeyParamsInfo::checkKeySize(uint32_t size)
+{
+  for (size_t i = 0; i < (sizeof(AES_KEY_SIZES) / sizeof(uint32_t)); i++)
+    {
+      if (AES_KEY_SIZES[i] == size)
+        return size;
+    }
+  return getDefaultSize();
+}
+
+uint32_t
+AesKeyParamsInfo::getDefaultSize()
+{
+  return AES_KEY_SIZES[0];
+}
+
+} // namespace ndn
diff --git a/src/security/key-params.hpp b/src/security/key-params.hpp
new file mode 100644
index 0000000..2cac26a
--- /dev/null
+++ b/src/security/key-params.hpp
@@ -0,0 +1,235 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_KEY_PARAMS_HPP
+#define NDN_SECURITY_KEY_PARAMS_HPP
+
+#include "security-common.hpp"
+
+namespace ndn {
+
+/**
+ * @brief Base class of key parameters.
+ *
+ * Its subclasses are used to store parameters for key generation.
+ */
+class KeyParams
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  virtual
+  ~KeyParams()
+  {
+  }
+
+  KeyType
+  getKeyType() const
+  {
+    return m_keyType;
+  }
+
+protected:
+  explicit
+  KeyParams(KeyType keyType)
+    : m_keyType(keyType)
+  {
+  }
+
+private:
+  KeyType m_keyType;
+};
+
+
+/// @brief RsaKeyParamInfo is used to initialize a SimplePublicKeyParams template for RSA key.
+class RsaKeyParamsInfo
+{
+public:
+  static KeyType
+  getType()
+  {
+    return KEY_TYPE_RSA;
+  }
+
+  /// @brief check if size is qualified, otherwise return the default key size.
+  static uint32_t
+  checkKeySize(uint32_t size);
+
+  static uint32_t
+  getDefaultSize();
+};
+
+/// @brief EcdsaKeyParamInfo is used to initialize a SimplePublicKeyParams template for ECDSA key.
+class EcdsaKeyParamsInfo
+{
+public:
+  static KeyType
+  getType()
+  {
+    return KEY_TYPE_ECDSA;
+  }
+
+  /// @brief check if size is qualified, otherwise return the default key size.
+  static uint32_t
+  checkKeySize(uint32_t size);
+
+  static uint32_t
+  getDefaultSize();
+};
+
+
+/// @brief SimplePublicKeyParams is a template for public keys with only one parameter: size.
+template<typename KeyParamsInfo>
+class SimplePublicKeyParams : public KeyParams
+{
+public:
+  explicit
+  SimplePublicKeyParams(uint32_t size = KeyParamsInfo::getDefaultSize())
+    : KeyParams(KeyParamsInfo::getType())
+  {
+    setKeySize(size);
+  }
+
+  explicit
+  SimplePublicKeyParams(const SimplePublicKeyParams& params)
+    : KeyParams(params)
+    , m_size(params.m_size)
+  {
+  }
+
+  explicit
+  SimplePublicKeyParams(const KeyParams& params)
+    : KeyParams(params.getKeyType())
+  {
+    throw KeyParams::Error("Incorrect key parameters (incompatible key type)");
+  }
+
+  uint32_t
+  getKeySize() const
+  {
+    return m_size;
+  }
+
+private:
+  void
+  setKeySize(uint32_t size)
+  {
+    m_size = KeyParamsInfo::checkKeySize(size);
+  }
+
+  uint32_t
+  getDefaultKeySize() const
+  {
+    return KeyParamsInfo::getDefaultSize();
+  }
+
+private:
+  uint32_t m_size;
+};
+
+/// @brief RsaKeyParams carries parameters for RSA key.
+typedef SimplePublicKeyParams<RsaKeyParamsInfo> RsaKeyParams;
+
+/// @brief EcdsaKeyParams carries parameters for ECDSA key.
+typedef SimplePublicKeyParams<EcdsaKeyParamsInfo> EcdsaKeyParams;
+
+
+/// @brief AesKeyParamsInfo is used to initialize a SimpleSymmetricKeyParams template for AES key.
+class AesKeyParamsInfo
+{
+public:
+  static KeyType
+  getType()
+  {
+    return KEY_TYPE_AES;
+  }
+
+  /// @brief check if size is qualified, otherwise return the default key size.
+  static uint32_t
+  checkKeySize(uint32_t size);
+
+  static uint32_t
+  getDefaultSize();
+};
+
+
+/// @brief SimpleSymmetricKeyParams is a template for symmetric keys with only one parameter: size.
+template<typename KeyParamsInfo>
+class SimpleSymmetricKeyParams : public KeyParams
+{
+public:
+  explicit
+  SimpleSymmetricKeyParams(uint32_t size = KeyParamsInfo::getDefaultSize())
+    : KeyParams(KeyParamsInfo::getType())
+  {
+    setKeySize(size);
+  }
+
+  explicit
+  SimpleSymmetricKeyParams(const SimpleSymmetricKeyParams& params)
+    : KeyParams(params)
+    , m_size(params.m_size)
+  {
+  }
+
+  explicit
+  SimpleSymmetricKeyParams(const KeyParams& params)
+  {
+    throw KeyParams::Error("Incorrect key parameters (incompatible key type)");
+  }
+
+  uint32_t
+  getKeySize() const
+  {
+    return m_size;
+  }
+
+private:
+  void
+  setKeySize(uint32_t size)
+  {
+    m_size = KeyParamsInfo::checkKeySize(size);
+  }
+
+  uint32_t
+  getDefaultKeySize() const
+  {
+    return KeyParamsInfo::getDefaultSize();
+  }
+
+private:
+  uint32_t m_size;
+
+};
+
+typedef SimpleSymmetricKeyParams<AesKeyParamsInfo> AesKeyParams;
+
+} // namespace ndn
+
+#endif // NDN_SECURITY_KEY_PARAMS_HPP
diff --git a/src/security/sec-tpm-file.cpp b/src/security/sec-tpm-file.cpp
index c8b460c..6634f68 100644
--- a/src/security/sec-tpm-file.cpp
+++ b/src/security/sec-tpm-file.cpp
@@ -38,13 +38,16 @@
 
 #include <algorithm>
 
-using namespace std;
-
 namespace ndn {
 
+using std::string;
+using std::ostringstream;
+using std::ofstream;
+
 class SecTpmFile::Impl
 {
 public:
+  explicit
   Impl(const string& dir)
   {
     if (dir.empty())
@@ -52,11 +55,11 @@
     else
       m_keystorePath = dir;
 
-    boost::filesystem::create_directories (m_keystorePath);
+    boost::filesystem::create_directories(m_keystorePath);
   }
 
   boost::filesystem::path
-  nameTransform(const string& keyName, const string& extension)
+  transformName(const string& keyName, const string& extension)
   {
     using namespace CryptoPP;
     string digest;
@@ -75,7 +78,7 @@
   string
   maintainMapping(const string& keyName)
   {
-    string keyFileName = nameTransform(keyName, "").string();
+    string keyFileName = transformName(keyName, "").string();
 
     ofstream outfile;
     string dirFile = (m_keystorePath / "mapping.txt").string();
@@ -95,10 +98,11 @@
 SecTpmFile::SecTpmFile(const string& dir)
   : m_impl(new Impl(dir))
   , m_inTerminal(false)
-{}
+{
+}
 
 void
-SecTpmFile::generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
+SecTpmFile::generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
 {
   string keyURI = keyName.toUri();
 
@@ -111,15 +115,16 @@
 
   try
     {
-      switch (keyType)
+      switch (params.getKeyType())
         {
         case KEY_TYPE_RSA:
           {
             using namespace CryptoPP;
-            AutoSeededRandomPool rng;
 
+            const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
+            AutoSeededRandomPool rng;
             InvertibleRSAFunction privateKey;
-            privateKey.Initialize(rng, keySize);
+            privateKey.Initialize(rng, rsaParams.getKeySize());
 
             string privateKeyFileName = keyFileName + ".pri";
             Base64Encoder privateKeySink(new FileSink(privateKeyFileName.c_str()));
@@ -141,6 +146,10 @@
           throw Error("Unsupported key type!");
         }
     }
+  catch (KeyParams::Error& e)
+    {
+      throw Error(e.what());
+    }
   catch (CryptoPP::Exception& e)
     {
       throw Error(e.what());
@@ -150,8 +159,8 @@
 void
 SecTpmFile::deleteKeyPairInTpm(const Name& keyName)
 {
-  boost::filesystem::path publicKeyPath(m_impl->nameTransform(keyName.toUri(), ".pub"));
-  boost::filesystem::path privateKeyPath(m_impl->nameTransform(keyName.toUri(), ".pri"));
+  boost::filesystem::path publicKeyPath(m_impl->transformName(keyName.toUri(), ".pub"));
+  boost::filesystem::path privateKeyPath(m_impl->transformName(keyName.toUri(), ".pri"));
 
   if (boost::filesystem::exists(publicKeyPath))
     boost::filesystem::remove(publicKeyPath);
@@ -172,7 +181,7 @@
   try
     {
       using namespace CryptoPP;
-      FileSource(m_impl->nameTransform(keyURI, ".pub").string().c_str(),
+      FileSource(m_impl->transformName(keyURI, ".pub").string().c_str(),
                  true,
                  new Base64Decoder(new FileSink(os)));
     }
@@ -189,7 +198,7 @@
 SecTpmFile::exportPrivateKeyPkcs8FromTpm(const Name& keyName)
 {
   OBufferStream privateKeyOs;
-  CryptoPP::FileSource(m_impl->nameTransform(keyName.toUri(), ".pri").string().c_str(), true,
+  CryptoPP::FileSource(m_impl->transformName(keyName.toUri(), ".pri").string().c_str(), true,
                        new CryptoPP::Base64Decoder(new CryptoPP::FileSink(privateKeyOs)));
 
   return privateKeyOs.buf();
@@ -251,7 +260,7 @@
 
       //Read private key
       ByteQueue bytes;
-      FileSource file(m_impl->nameTransform(keyURI, ".pri").string().c_str(),
+      FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
                       true, new Base64Decoder);
       file.TransferTo(bytes);
       bytes.MessageEnd();
@@ -300,7 +309,7 @@
 
   //       //Read private key
   //       ByteQueue bytes;
-  //       FileSource file(m_impl->nameTransform(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
+  //       FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
   //       file.TransferTo(bytes);
   //       bytes.MessageEnd();
   //       RSA::PrivateKey privateKey;
@@ -320,27 +329,27 @@
   //   {
   //     throw Error("Symmetric encryption is not implemented!");
   //     // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
-  //     // 	throw Error("symmetric key doesn't exist");
+  //     //     throw Error("symmetric key doesn't exist");
 
   //     // try{
-  //     // 	string keyBits;
-  //     // 	string symKeyFileName = m_impl->nameTransform(keyURI, ".key");
-  //     // 	FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
+  //     //     string keyBits;
+  //     //     string symKeyFileName = m_impl->transformName(keyURI, ".key");
+  //     //     FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
 
-  //     // 	using CryptoPP::AES;
-  //     // 	AutoSeededRandomPool rnd;
-  //     // 	byte iv[AES::BLOCKSIZE];
-  //     // 	rnd.GenerateBlock(iv, AES::BLOCKSIZE);
+  //     //     using CryptoPP::AES;
+  //     //     AutoSeededRandomPool rnd;
+  //     //     byte iv[AES::BLOCKSIZE];
+  //     //     rnd.GenerateBlock(iv, AES::BLOCKSIZE);
 
-  //     // 	CFB_Mode<AES>::Decryption decryptor;
-  //     // 	decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
+  //     //     CFB_Mode<AES>::Decryption decryptor;
+  //     //     decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
 
-  //     // 	OBufferStream os;
-  //     // 	StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
-  //     // 	return os.buf();
+  //     //     OBufferStream os;
+  //     //     StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
+  //     //     return os.buf();
 
   //     // }catch (CryptoPP::Exception& e){
-  //     // 	throw Error(e.what());
+  //     //     throw Error(e.what());
   //     // }
   //   }
 }
@@ -363,7 +372,7 @@
 
   //         //Read private key
   //         ByteQueue bytes;
-  //         FileSource file(m_impl->nameTransform(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
+  //         FileSource file(m_impl->transformName(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
   //         file.TransferTo(bytes);
   //         bytes.MessageEnd();
   //         RSA::PublicKey publicKey;
@@ -383,33 +392,33 @@
   //   {
   //     throw Error("Symmetric encryption is not implemented!");
   //     // if (!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
-  //     // 	throw Error("symmetric key doesn't exist");
+  //     //     throw Error("symmetric key doesn't exist");
 
   //     // try{
-  //     // 	string keyBits;
-  //     // 	string symKeyFileName = m_impl->nameTransform(keyURI, ".key");
-  //     // 	FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
+  //     //     string keyBits;
+  //     //     string symKeyFileName = m_impl->transformName(keyURI, ".key");
+  //     //     FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
 
-  //     // 	using CryptoPP::AES;
-  //     // 	AutoSeededRandomPool rnd;
-  //     // 	byte iv[AES::BLOCKSIZE];
-  //     // 	rnd.GenerateBlock(iv, AES::BLOCKSIZE);
+  //     //     using CryptoPP::AES;
+  //     //     AutoSeededRandomPool rnd;
+  //     //     byte iv[AES::BLOCKSIZE];
+  //     //     rnd.GenerateBlock(iv, AES::BLOCKSIZE);
 
-  //     // 	CFB_Mode<AES>::Encryption encryptor;
-  //     // 	encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
+  //     //     CFB_Mode<AES>::Encryption encryptor;
+  //     //     encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
 
-  //     // 	OBufferStream os;
-  //     // 	StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
-  //     // 	return os.buf();
+  //     //     OBufferStream os;
+  //     //     StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
+  //     //     return os.buf();
   //     // }catch (CryptoPP::Exception& e){
-  //     // 	throw Error(e.what());
+  //     //     throw Error(e.what());
   //     // }
   //   }
 }
 
 
 void
-SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
+SecTpmFile::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
 {
   throw Error("SecTpmFile::generateSymmetricKeyInTpm is not supported!");
   // string keyURI = keyName.toUri();
@@ -449,21 +458,21 @@
   string keyURI = keyName.toUri();
   if (keyClass == KEY_CLASS_PUBLIC)
     {
-      if (boost::filesystem::exists(m_impl->nameTransform(keyURI, ".pub")))
+      if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pub")))
         return true;
       else
         return false;
     }
   if (keyClass == KEY_CLASS_PRIVATE)
     {
-      if (boost::filesystem::exists(m_impl->nameTransform(keyURI, ".pri")))
+      if (boost::filesystem::exists(m_impl->transformName(keyURI, ".pri")))
         return true;
       else
         return false;
     }
   if (keyClass == KEY_CLASS_SYMMETRIC)
     {
-      if (boost::filesystem::exists(m_impl->nameTransform(keyURI, ".key")))
+      if (boost::filesystem::exists(m_impl->transformName(keyURI, ".key")))
         return true;
       else
         return false;
diff --git a/src/security/sec-tpm-file.hpp b/src/security/sec-tpm-file.hpp
index d878ad6..3c97e4e 100644
--- a/src/security/sec-tpm-file.hpp
+++ b/src/security/sec-tpm-file.hpp
@@ -88,7 +88,7 @@
   }
 
   virtual void
-  generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize);
+  generateKeyPairInTpm(const Name& keyName, const KeyParams& params);
 
   virtual void
   deleteKeyPairInTpm(const Name& keyName);
@@ -107,7 +107,7 @@
   encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);
 
   virtual void
-  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);
+  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params);
 
   virtual bool
   doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);
@@ -121,9 +121,10 @@
   }
 
 protected:
-  /******************************
-   * From TrustedPlatformModule *
-   ******************************/
+  ////////////////////////////////
+  // From TrustedPlatformModule //
+  ////////////////////////////////
+
   virtual ConstBufferPtr
   exportPrivateKeyPkcs8FromTpm(const Name& keyName);
 
diff --git a/src/security/sec-tpm-osx.cpp b/src/security/sec-tpm-osx.cpp
index a5a7159..031632d 100644
--- a/src/security/sec-tpm-osx.cpp
+++ b/src/security/sec-tpm-osx.cpp
@@ -41,10 +41,10 @@
 
 #include <Security/SecDigestTransform.h>
 
-using namespace std;
-
 namespace ndn {
 
+using std::string;
+
 /**
  * @brief Helper class to wrap CoreFoundation object pointers
  *
@@ -256,7 +256,7 @@
 SecTpmOsx::setTpmPassword(const uint8_t* password, size_t passwordLength)
 {
   m_impl->m_passwordSet = true;
-  memset(const_cast<char*>(m_impl->m_password.c_str()), 0, m_impl->m_password.size());
+  std::fill(m_impl->m_password.begin(), m_impl->m_password.end(), 0);
   m_impl->m_password.clear();
   m_impl->m_password.append(reinterpret_cast<const char*>(password), passwordLength);
 }
@@ -265,7 +265,7 @@
 SecTpmOsx::resetTpmPassword()
 {
   m_impl->m_passwordSet = false;
-  memset(const_cast<char*>(m_impl->m_password.c_str()), 0, m_impl->m_password.size());
+  std::fill(m_impl->m_password.begin(), m_impl->m_password.end(), 0);
   m_impl->m_password.clear();
 }
 
@@ -363,8 +363,9 @@
 }
 
 void
-SecTpmOsx::generateKeyPairInTpmInternal(const Name& keyName, KeyType keyType,
-                                        int keySize, bool needRetry)
+SecTpmOsx::generateKeyPairInTpmInternal(const Name& keyName,
+                                        const KeyParams& params,
+                                        bool needRetry)
 {
 
   if (doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
@@ -385,6 +386,20 @@
                               &kCFTypeDictionaryKeyCallBacks,
                               0);
 
+  KeyType keyType = params.getKeyType();
+  uint32_t keySize;
+  switch (keyType)
+    {
+    case KEY_TYPE_RSA:
+      {
+        const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
+        keySize = rsaParams.getKeySize();
+        break;
+      }
+    default:
+      throw Error("Fail to create a key pair: Unsupported key type");
+    }
+
   CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(0, kCFNumberIntType, &keySize);
 
   CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, m_impl->getAsymKeyType(keyType));
@@ -392,6 +407,7 @@
   CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
 
   CFReleaser<SecKeyRef> publicKey, privateKey;
+  // C-style cast is used as per Apple convention
   OSStatus res = SecKeyGeneratePair((CFDictionaryRef)attrDict.get(),
                                     &publicKey.get(), &privateKey.get());
 
@@ -403,7 +419,7 @@
   if (res == errSecAuthFailed && !needRetry)
     {
       if (unlockTpm(0, 0, false))
-        generateKeyPairInTpmInternal(keyName, keyType, keySize, true);
+        generateKeyPairInTpmInternal(keyName, params, true);
       else
         throw Error("Fail to unlock the keychain");
     }
@@ -442,7 +458,7 @@
 }
 
 void
-SecTpmOsx::generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
+SecTpmOsx::generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params)
 {
   throw Error("SecTpmOsx::generateSymmetricKeyInTpm is not supported");
   // if (doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
@@ -537,7 +553,7 @@
   FileSink sink(pkcs1Os);
 
   uint32_t version = 0;
-  OID algorithm("1.2.840.113549.1.1.1");
+  OID algorithm("1.2.840.113549.1.1.1"); // "RSA encryption"
   SecByteBlock rawKeyBits;
   // PrivateKeyInfo ::= SEQUENCE {
   //   version              INTEGER,
@@ -645,6 +661,7 @@
         return false;
     }
 
+  // C-style cast is used as per Apple convention
   SecKeychainItemRef privateKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems.get(), 0);
   SecKeychainAttribute attrs[1]; // maximum number of attributes
   SecKeychainAttributeList attrList = { 0, attrs };
@@ -652,7 +669,7 @@
   {
     attrs[attrList.count].tag = kSecKeyPrintName;
     attrs[attrList.count].length = keyUri.size();
-    attrs[attrList.count].data = (void *)keyUri.c_str();
+    attrs[attrList.count].data = const_cast<char*>(keyUri.c_str());
     attrList.count++;
   }
 
@@ -697,6 +714,7 @@
   if (res != errSecSuccess)
     return false;
 
+  // C-style cast is used as per Apple convention
   SecKeychainItemRef publicKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems.get(), 0);
   SecKeychainAttribute attrs[1]; // maximum number of attributes
   SecKeychainAttributeList attrList = { 0, attrs };
@@ -704,7 +722,7 @@
   {
     attrs[attrList.count].tag = kSecKeyPrintName;
     attrs[attrList.count].length = keyUri.size();
-    attrs[attrList.count].data = (void *)keyUri.c_str();
+    attrs[attrList.count].data = const_cast<char*>(keyUri.c_str());
     attrList.count++;
   }
 
@@ -735,16 +753,17 @@
     }
 
   CFReleaser<CFErrorRef> error;
+  // C-style cast is used as per Apple convention
   CFReleaser<SecTransformRef> signer = SecSignTransformCreate((SecKeyRef)privateKey.get(),
                                                               &error.get());
   if (error.get() != 0)
     throw Error("Fail to create signer");
 
   // Set input
-  Boolean set_res = SecTransformSetAttribute(signer.get(),
-                                             kSecTransformInputAttributeName,
-                                             dataRef.get(),
-                                             &error.get());
+  SecTransformSetAttribute(signer.get(),
+                           kSecTransformInputAttributeName,
+                           dataRef.get(),
+                           &error.get());
   if (error.get() != 0)
     throw Error("Fail to configure input of signer");
 
@@ -757,24 +776,25 @@
     throw Error("Fail to configure digest algorithm of signer");
 
   // Set padding type
-  set_res = SecTransformSetAttribute(signer.get(),
-                                     kSecDigestTypeAttribute,
-                                     m_impl->getDigestAlgorithm(digestAlgorithm),
-                                     &error.get());
+  SecTransformSetAttribute(signer.get(),
+                           kSecDigestTypeAttribute,
+                           m_impl->getDigestAlgorithm(digestAlgorithm),
+                           &error.get());
   if (error.get() != 0)
     throw Error("Fail to configure digest algorithm of signer");
 
   // Set padding attribute
   long digestSize = m_impl->getDigestSize(digestAlgorithm);
   CFReleaser<CFNumberRef> cfDigestSize = CFNumberCreate(0, kCFNumberLongType, &digestSize);
-  set_res = SecTransformSetAttribute(signer.get(),
-                                     kSecDigestLengthAttribute,
-                                     cfDigestSize.get(),
-                                     &error.get());
+  SecTransformSetAttribute(signer.get(),
+                           kSecDigestLengthAttribute,
+                           cfDigestSize.get(),
+                           &error.get());
   if (error.get() != 0)
     throw Error("Fail to configure digest size of signer");
 
   // Actually sign
+  // C-style cast is used as per Apple convention
   CFReleaser<CFDataRef> signature = (CFDataRef)SecTransformExecute(signer.get(), &error.get());
   if (error.get() != 0)
     {
@@ -856,37 +876,38 @@
         }
 
       CFReleaser<SecAccessRef> accRef;
-      OSStatus acc_res = SecKeychainItemCopyAccess(privateKey.get(), &accRef.get());
+      SecKeychainItemCopyAccess(privateKey.get(), &accRef.get());
 
       CFReleaser<CFArrayRef> signACL = SecAccessCopyMatchingACLList(accRef.get(),
                                                                     kSecACLAuthorizationSign);
 
+      // C-style cast is used as per Apple convention
       SecACLRef aclRef = (SecACLRef)CFArrayGetValueAtIndex(signACL.get(), 0);
 
       CFReleaser<CFArrayRef> appList;
       CFReleaser<CFStringRef> description;
       SecKeychainPromptSelector promptSelector;
-      OSStatus acl_res = SecACLCopyContents(aclRef,
-                                            &appList.get(),
-                                            &description.get(),
-                                            &promptSelector);
+      SecACLCopyContents(aclRef,
+                         &appList.get(),
+                         &description.get(),
+                         &promptSelector);
 
       CFReleaser<CFMutableArrayRef> newAppList = CFArrayCreateMutableCopy(0,
                                                                           0,
                                                                           appList.get());
 
       CFReleaser<SecTrustedApplicationRef> trustedApp;
-      acl_res = SecTrustedApplicationCreateFromPath(appPath.c_str(),
-                                                    &trustedApp.get());
+      SecTrustedApplicationCreateFromPath(appPath.c_str(),
+                                          &trustedApp.get());
 
       CFArrayAppendValue(newAppList.get(), trustedApp.get());
 
-      acl_res = SecACLSetContents(aclRef,
-                                  newAppList.get(),
-                                  description.get(),
-                                  promptSelector);
+      SecACLSetContents(aclRef,
+                        newAppList.get(),
+                        description.get(),
+                        promptSelector);
 
-      acc_res = SecKeychainItemSetAccess(privateKey.get(), accRef.get());
+      SecKeychainItemSetAccess(privateKey.get(), accRef.get());
     }
 }
 
@@ -951,6 +972,7 @@
   CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);
 
   CFReleaser<SecKeychainItemRef> itemRef;
+  // C-style cast is used as per Apple convention
   OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&itemRef.get());
 
   if (res == errSecSuccess)
@@ -963,7 +985,7 @@
 bool
 SecTpmOsx::generateRandomBlock(uint8_t* res, size_t size)
 {
-  return (SecRandomCopyBytes(kSecRandomDefault, size, res) == 0);
+  return SecRandomCopyBytes(kSecRandomDefault, size, res) == 0;
 }
 
 ////////////////////////////////
@@ -991,6 +1013,7 @@
   CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);
 
   CFReleaser<SecKeychainItemRef> keyItem;
+  // C-style cast is used as per Apple convention
   OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&keyItem.get());
 
   if (res != errSecSuccess)
@@ -1013,7 +1036,7 @@
 CFTypeRef
 SecTpmOsx::Impl::getAsymKeyType(KeyType keyType)
 {
-  switch (keyType){
+  switch (keyType) {
   case KEY_TYPE_RSA:
     return kSecAttrKeyTypeRSA;
   default:
@@ -1024,7 +1047,7 @@
 CFTypeRef
 SecTpmOsx::Impl::getSymKeyType(KeyType keyType)
 {
-  switch (keyType){
+  switch (keyType) {
   case KEY_TYPE_AES:
     return kSecAttrKeyTypeAES;
   default:
@@ -1035,7 +1058,7 @@
 CFTypeRef
 SecTpmOsx::Impl::getKeyClass(KeyClass keyClass)
 {
-  switch (keyClass){
+  switch (keyClass) {
   case KEY_CLASS_PRIVATE:
     return kSecAttrKeyClassPrivate;
   case KEY_CLASS_PUBLIC:
@@ -1050,13 +1073,7 @@
 CFStringRef
 SecTpmOsx::Impl::getDigestAlgorithm(DigestAlgorithm digestAlgo)
 {
-  switch (digestAlgo){
-    // case DIGEST_MD2:
-    //   return kSecDigestMD2;
-    // case DIGEST_MD5:
-    //   return kSecDigestMD5;
-    // case DIGEST_SHA1:
-    //   return kSecDigestSHA1;
+  switch (digestAlgo) {
   case DIGEST_ALGORITHM_SHA256:
     return kSecDigestSHA2;
   default:
@@ -1067,13 +1084,9 @@
 long
 SecTpmOsx::Impl::getDigestSize(DigestAlgorithm digestAlgo)
 {
-  switch (digestAlgo){
+  switch (digestAlgo) {
   case DIGEST_ALGORITHM_SHA256:
     return 256;
-    // case DIGEST_SHA1:
-    // case DIGEST_MD2:
-    // case DIGEST_MD5:
-    //   return 0;
   default:
     return -1;
   }
diff --git a/src/security/sec-tpm-osx.hpp b/src/security/sec-tpm-osx.hpp
index 306e417..fca8dda 100644
--- a/src/security/sec-tpm-osx.hpp
+++ b/src/security/sec-tpm-osx.hpp
@@ -53,9 +53,7 @@
   ~SecTpmOsx();
 
 
-  /******************************
-   * From TrustedPlatformModule *
-   ******************************/
+  // Following methods are inherited from SecTpm
 
   virtual void
   setTpmPassword(const uint8_t* password, size_t passwordLength);
@@ -76,9 +74,9 @@
   unlockTpm(const char* password, size_t passwordLength, bool usePassword);
 
   virtual void
-  generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
+  generateKeyPairInTpm(const Name& keyName, const KeyParams& params)
   {
-    generateKeyPairInTpmInternal(keyName, keyType, keySize, false);
+    generateKeyPairInTpmInternal(keyName, params, false);
   }
 
   virtual void
@@ -104,7 +102,7 @@
   encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);
 
   virtual void
-  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);
+  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params);
 
   virtual bool
   doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);
@@ -116,9 +114,7 @@
   addAppToAcl(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl);
 
 protected:
-  /******************************
-   * From TrustedPlatformModule *
-   ******************************/
+  // Following methods are inherited from SecTpm
   virtual ConstBufferPtr
   exportPrivateKeyPkcs8FromTpm(const Name& keyName)
   {
@@ -134,11 +130,9 @@
   virtual bool
   importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size);
 
-  /******************************
-   *       OSX-specifics        *
-   ******************************/
+  // Following methods are OSX-specific
   void
-  generateKeyPairInTpmInternal(const Name& keyName, KeyType keyType, int keySize, bool needRetry);
+  generateKeyPairInTpmInternal(const Name& keyName, const KeyParams& params, bool needRetry);
 
   void
   deleteKeyPairInTpmInternal(const Name& keyName, bool needRetry);
diff --git a/src/security/sec-tpm.cpp b/src/security/sec-tpm.cpp
index 2c3d976..2011a95 100644
--- a/src/security/sec-tpm.cpp
+++ b/src/security/sec-tpm.cpp
@@ -295,5 +295,40 @@
   return true;
 }
 
+bool
+SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
+{
+  bool isInitialized = false;
+
+  char* pw0 = 0;
+
+  pw0 = getpass(prompt.c_str());
+  if (0 == pw0)
+    return false;
+  std::string password1 = pw0;
+  memset(pw0, 0, strlen(pw0));
+
+  pw0 = getpass("Confirm:");
+  if (0 == pw0)
+    {
+      std::fill(password1.begin(), password1.end(), 0);
+      return false;
+    }
+
+  if (0 == password1.compare(pw0))
+    {
+      isInitialized = true;
+      password.swap(password1);
+    }
+
+  std::fill(password1.begin(), password1.end(), 0);
+  memset(pw0, 0, strlen(pw0));
+
+  if (password.empty())
+    return false;
+
+  return isInitialized;
+}
+
 
 } // namespace ndn
diff --git a/src/security/sec-tpm.hpp b/src/security/sec-tpm.hpp
index 8acb1b5..031aa2b 100644
--- a/src/security/sec-tpm.hpp
+++ b/src/security/sec-tpm.hpp
@@ -29,6 +29,7 @@
 #include "../name.hpp"
 #include "../data.hpp"
 #include "public-key.hpp"
+#include "key-params.hpp"
 
 namespace ndn {
 
@@ -110,12 +111,11 @@
    * @brief Generate a pair of asymmetric keys.
    *
    * @param keyName The name of the key pair.
-   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
-   * @param keySize The size of the key pair.
+   * @param params The parameters of key.
    * @throws SecTpm::Error if fails.
    */
   virtual void
-  generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
+  generateKeyPairInTpm(const Name& keyName, const KeyParams& params) = 0;
 
   /**
    * @brief Delete a key pair of asymmetric keys.
@@ -180,12 +180,11 @@
    * @brief Generate a symmetric key.
    *
    * @param keyName The name of the key.
-   * @param keyType The type of the key, e.g. KEY_TYPE_AES.
-   * @param keySize The size of the key.
+   * @param params The parameter of the key.
    * @throws SecTpm::Error if key generating fails.
    */
   virtual void
-  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
+  generateSymmetricKeyInTpm(const Name& keyName, const KeyParams& params) = 0;
 
   /**
    * @brief Check if a particular key exists.
@@ -287,47 +286,10 @@
    * @param prompt Prompt for password, i.e., "Password for key:"
    * @return true if password has been obtained.
    */
-  inline virtual bool
+  virtual bool
   getImpExpPassWord(std::string& password, const std::string& prompt);
 };
 
-inline bool
-SecTpm::getImpExpPassWord(std::string& password, const std::string& prompt)
-{
-  int result = false;
-
-  char* pw0 = NULL;
-
-  pw0 = getpass(prompt.c_str());
-  if (!pw0)
-    return false;
-  std::string password1 = pw0;
-  memset(pw0, 0, strlen(pw0));
-
-  pw0 = getpass("Confirm:");
-  if (!pw0)
-    {
-      char* pw1 = const_cast<char*>(password1.c_str());
-      memset(pw1, 0, password1.size());
-      return false;
-    }
-
-  if (!password1.compare(pw0))
-    {
-      result = true;
-      password.swap(password1);
-    }
-
-  char* pw1 = const_cast<char*>(password1.c_str());
-  memset(pw1, 0, password1.size());
-  memset(pw0, 0, strlen(pw0));
-
-  if (password.empty())
-    return false;
-
-  return result;
-}
-
 } // namespace ndn
 
 #endif //NDN_SECURITY_SEC_TPM_HPP
diff --git a/src/security/security-common.hpp b/src/security/security-common.hpp
index b6b3119..ad3f671 100644
--- a/src/security/security-common.hpp
+++ b/src/security/security-common.hpp
@@ -55,9 +55,6 @@
 };
 
 enum DigestAlgorithm {
-  // DIGEST_ALGORITHM_MD2,
-  // DIGEST_ALGORITHM_MD5,
-  // DIGEST_ALGORITHM_SHA1,
   DIGEST_ALGORITHM_SHA256
 };