diff --git a/src/security/pib/key.cpp b/src/security/pib/key.cpp
index c59a39d..51f368c 100644
--- a/src/security/pib/key.cpp
+++ b/src/security/pib/key.cpp
@@ -22,6 +22,7 @@
 #include "key.hpp"
 #include "pib-impl.hpp"
 #include "pib.hpp"
+#include "../v2/certificate.hpp"
 
 namespace ndn {
 namespace security {
@@ -196,5 +197,19 @@
     BOOST_THROW_EXCEPTION(std::domain_error("Invalid Key instance"));
 }
 
+namespace v2 {
+
+Name
+constructKeyName(const Name& identity, const name::Component& keyId)
+{
+  Name keyName = identity;
+  keyName
+    .append(Certificate::KEY_COMPONENT)
+    .append(keyId);
+  return keyName;
+}
+
+} // namespace v2
+
 } // namespace security
 } // namespace ndn
diff --git a/src/security/pib/key.hpp b/src/security/pib/key.hpp
index 7118149..53a0ba1 100644
--- a/src/security/pib/key.hpp
+++ b/src/security/pib/key.hpp
@@ -201,7 +201,17 @@
   shared_ptr<PibImpl> m_impl;
 };
 
+namespace v2 {
+
+/**
+ * @brief Construct key name based on the appropriate naming conventions
+ */
+Name
+constructKeyName(const Name& identity, const name::Component& keyId);
+
+} // namespace v2
+
 } // namespace security
 } // namespace ndn
 
-#endif // NDN_SECURITY_PIB_PIB_HPP
+#endif // NDN_SECURITY_PIB_KEY_HPP
diff --git a/src/security/tpm/back-end-file.cpp b/src/security/tpm/back-end-file.cpp
new file mode 100644
index 0000000..f16d7cf
--- /dev/null
+++ b/src/security/tpm/back-end-file.cpp
@@ -0,0 +1,192 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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 "back-end-file.hpp"
+#include "key-handle-mem.hpp"
+#include "../transform.hpp"
+#include "../transform/private-key.hpp"
+#include "../../encoding/buffer-stream.hpp"
+#include <unordered_map>
+#include <fstream>
+#include <cstdlib>
+#include <boost/filesystem.hpp>
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+using transform::PrivateKey;
+
+class BackEndFile::Impl
+{
+public:
+  explicit
+  Impl(const std::string& dir)
+  {
+    if (!dir.empty()) {
+      keystorePath = boost::filesystem::path(dir);
+    }
+#ifdef NDN_CXX_HAVE_TESTS
+    else if (getenv("TEST_HOME") != nullptr) {
+      keystorePath = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
+    }
+#endif // NDN_CXX_HAVE_TESTS
+    else if (getenv("HOME") != nullptr) {
+      keystorePath = boost::filesystem::path(getenv("HOME")) / ".ndn";
+    }
+    else {
+      keystorePath = boost::filesystem::current_path() / ".ndn";
+    }
+
+    keystorePath /= "ndnsec-key-file";
+    boost::filesystem::create_directories(keystorePath);
+  }
+
+  boost::filesystem::path
+  toFileName(const Name& keyName)
+  {
+    std::stringstream os;
+    {
+      using namespace transform;
+      bufferSource(keyName.wireEncode().wire(), keyName.wireEncode().size()) >>
+        digestFilter(DigestAlgorithm::SHA256) >> hexEncode() >> streamSink(os);
+    }
+    return keystorePath / (os.str() + ".privkey");
+  }
+
+public:
+  boost::filesystem::path keystorePath;
+};
+
+BackEndFile::BackEndFile(const std::string& location)
+  : m_impl(new Impl(location))
+{
+}
+
+BackEndFile::~BackEndFile() = default;
+
+bool
+BackEndFile::doHasKey(const Name& keyName) const
+{
+  if (!boost::filesystem::exists(m_impl->toFileName(keyName)))
+    return false;
+
+  try {
+    loadKey(keyName);
+    return true;
+  }
+  catch (const std::runtime_error&) {
+    return false;
+  }
+}
+
+unique_ptr<KeyHandle>
+BackEndFile::doGetKeyHandle(const Name& keyName) const
+{
+  if (!doHasKey(keyName))
+    return nullptr;
+
+  return make_unique<KeyHandleMem>(loadKey(keyName));
+}
+
+unique_ptr<KeyHandle>
+BackEndFile::doCreateKey(const Name& identityName, const KeyParams& params)
+{
+  shared_ptr<PrivateKey> key(transform::generatePrivateKey(params).release());
+  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleMem>(key);
+
+  setKeyName(*keyHandle, identityName, params);
+
+  try {
+    saveKey(keyHandle->getKeyName(), key);
+    return keyHandle;
+  }
+  catch (const std::runtime_error& e) {
+    BOOST_THROW_EXCEPTION(Error(std::string("Cannot write key to disk: ") + e.what()));
+  }
+}
+
+void
+BackEndFile::doDeleteKey(const Name& keyName)
+{
+  boost::filesystem::path keyPath(m_impl->toFileName(keyName));
+
+  if (boost::filesystem::exists(keyPath)) {
+    try {
+      boost::filesystem::remove(keyPath);
+    }
+    catch (const boost::filesystem::filesystem_error&) {
+      BOOST_THROW_EXCEPTION(Error("Cannot delete key"));
+    }
+  }
+}
+
+ConstBufferPtr
+BackEndFile::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
+{
+  shared_ptr<PrivateKey> key;
+  try {
+    key = loadKey(keyName);
+  }
+  catch (const PrivateKey::Error&) {
+    BOOST_THROW_EXCEPTION(Error("Cannot export private key"));
+  }
+  OBufferStream os;
+  key->savePkcs8(os, pw, pwLen);
+  return os.buf();
+}
+
+void
+BackEndFile::doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen)
+{
+  try {
+    auto key = make_shared<PrivateKey>();
+    key->loadPkcs8(buf, size, pw, pwLen);
+    saveKey(keyName, key);
+  }
+  catch (const PrivateKey::Error&) {
+    BOOST_THROW_EXCEPTION(Error("Cannot import private key"));
+  }
+}
+
+shared_ptr<PrivateKey>
+BackEndFile::loadKey(const Name& keyName) const
+{
+  auto key = make_shared<PrivateKey>();
+  std::fstream is(m_impl->toFileName(keyName).string(), std::ios_base::in);
+  key->loadPkcs1Base64(is);
+  return key;
+}
+
+void
+BackEndFile::saveKey(const Name& keyName, shared_ptr<PrivateKey> key)
+{
+  std::string fileName = m_impl->toFileName(keyName).string();
+  std::fstream os(fileName, std::ios_base::out);
+  key->savePkcs1Base64(os);
+
+  // set file permission
+  chmod(fileName.c_str(), 0000400);
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/back-end-file.hpp b/src/security/tpm/back-end-file.hpp
new file mode 100644
index 0000000..02b575f
--- /dev/null
+++ b/src/security/tpm/back-end-file.hpp
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_BACK_END_FILE_HPP
+#define NDN_SECURITY_TPM_BACK_END_FILE_HPP
+
+#include "back-end.hpp"
+
+namespace ndn {
+namespace security {
+namespace transform {
+class PrivateKey;
+} // namespace transform
+
+namespace tpm {
+
+/**
+ * @brief The back-end implementation of file-based TPM.
+ *
+ * In this TPM, each private key is stored in a separate file with permission 0400, i.e.,
+ * owner read-only.  The key is stored in PKCS #1 format in base64 encoding.
+ */
+class BackEndFile : public BackEnd
+{
+public:
+  class Error : public BackEnd::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : BackEnd::Error(what)
+    {
+    }
+  };
+
+public:
+  explicit
+  BackEndFile(const std::string& location = "");
+
+  ~BackEndFile() override;
+
+private: // inherited from tpm::BackEnd
+  /**
+   * @return True if a key with name @p keyName exists in TPM.
+   */
+  bool
+  doHasKey(const Name& keyName) const final;
+
+  /**
+   * @return The handle of a key with name @p keyName, or nullptr if the key does not exist
+   */
+  unique_ptr<KeyHandle>
+  doGetKeyHandle(const Name& keyName) const final;
+
+  /**
+   * @brief Create key for @p identityName according to @p params.
+   *
+   * The created key is named as: /<identityName>/[keyId]/KEY
+   * The key name is set in the returned KeyHandle.
+   *
+   * If the key with the same name exists, the old key will be overwritten.
+   * The behavior of using KeyHandler of removed key is undefined.
+   *
+   * @return The handle of the created key.
+   */
+  unique_ptr<KeyHandle>
+  doCreateKey(const Name& identityName, const KeyParams& params) final;
+
+  /**
+   * @brief Delete a key with name @p keyName.
+   *
+   * @throws Error if the deletion fails.
+   */
+  void
+  doDeleteKey(const Name& keyName) final;
+
+  /**
+   * @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
+   * @throws Error if the key cannot be exported, e.g., not enough privilege
+   */
+  ConstBufferPtr
+  doExportKey(const Name& keyName, const char* pw, size_t pwLen) final;
+
+  /**
+   * @brief Import a private key in encrypted PKCS #8 format
+   *
+   * @param keyName The name of imported private key
+   * @param buf Pointer to the key in encrypted PKCS #8 format
+   * @param size The size of the key in encrypted PKCS #8 format
+   * @param pw The password to decrypt the key
+   * @param pwLen The length of the password
+   * @throws Error if import fails.
+   */
+  void
+  doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen) final;
+
+private:
+  /**
+   * @brief Load a private key with name @p keyName from the key file directory
+   */
+  shared_ptr<transform::PrivateKey>
+  loadKey(const Name& keyName) const;
+
+  /**
+   * @brief Save a private key with name @p keyName into the key file directory
+   */
+  void
+  saveKey(const Name& keyName, shared_ptr<transform::PrivateKey> key);
+
+private:
+  class Impl;
+  unique_ptr<Impl> m_impl;
+};
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_BACK_END_FILE_HPP
diff --git a/src/security/tpm/back-end-mem.cpp b/src/security/tpm/back-end-mem.cpp
new file mode 100644
index 0000000..beac9db
--- /dev/null
+++ b/src/security/tpm/back-end-mem.cpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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 "back-end-mem.hpp"
+#include "key-handle-mem.hpp"
+#include "../transform/private-key.hpp"
+#include "../../encoding/buffer-stream.hpp"
+#include <unordered_map>
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+using transform::PrivateKey;
+
+class BackEndMem::Impl
+{
+public:
+  std::unordered_map<Name, shared_ptr<PrivateKey>> keys;
+};
+
+BackEndMem::BackEndMem()
+  : m_impl(new Impl)
+{
+}
+
+BackEndMem::~BackEndMem() = default;
+
+bool
+BackEndMem::doHasKey(const Name& keyName) const
+{
+  return (m_impl->keys.count(keyName) > 0);
+}
+
+unique_ptr<KeyHandle>
+BackEndMem::doGetKeyHandle(const Name& keyName) const
+{
+  auto it = m_impl->keys.find(keyName);
+  if (it == m_impl->keys.end())
+    return nullptr;
+  return make_unique<KeyHandleMem>(it->second);
+}
+
+unique_ptr<KeyHandle>
+BackEndMem::doCreateKey(const Name& identityName, const KeyParams& params)
+{
+  shared_ptr<PrivateKey> key(transform::generatePrivateKey(params).release());
+  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleMem>(key);
+
+  setKeyName(*keyHandle, identityName, params);
+
+  m_impl->keys[keyHandle->getKeyName()] = key;
+  return keyHandle;
+}
+
+void
+BackEndMem::doDeleteKey(const Name& keyName)
+{
+  m_impl->keys.erase(keyName);
+}
+
+ConstBufferPtr
+BackEndMem::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
+{
+  OBufferStream os;
+  m_impl->keys[keyName]->savePkcs8(os, pw, pwLen);
+  return os.buf();
+}
+
+void
+BackEndMem::doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen)
+{
+  try {
+    auto key = make_shared<PrivateKey>();
+    key->loadPkcs8(buf, size, pw, pwLen);
+    m_impl->keys[keyName] = key;
+  }
+  catch (const PrivateKey::Error& e) {
+    BOOST_THROW_EXCEPTION(Error(std::string("Cannot import private key: ") + e.what()));
+  }
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/back-end-mem.hpp b/src/security/tpm/back-end-mem.hpp
new file mode 100644
index 0000000..4253b5e
--- /dev/null
+++ b/src/security/tpm/back-end-mem.hpp
@@ -0,0 +1,117 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_BACK_END_MEM_HPP
+#define NDN_SECURITY_TPM_BACK_END_MEM_HPP
+
+#include "back-end.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+/**
+ * @brief The back-end implementation of in-memory TPM.
+ */
+class BackEndMem : public BackEnd
+{
+public:
+  class Error : public BackEnd::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : BackEnd::Error(what)
+    {
+    }
+  };
+
+public:
+  explicit
+  BackEndMem();
+
+  ~BackEndMem() override;
+
+private: // inherited from tpm::BackEnd
+
+  /**
+   * @return True if a key with name @p keyName exists in TPM.
+   */
+  bool
+  doHasKey(const Name& keyName) const final;
+
+  /**
+   * @return The handle of a key with name @p keyName, or nullptr if the key does not exist
+   */
+  unique_ptr<KeyHandle>
+  doGetKeyHandle(const Name& keyName) const final;
+
+  /**
+   * @brief Create key for @p identityName according to @p params.
+   *
+   * The created key is named as: /<identityName>/[keyId]/KEY
+   * The key name is set in the returned KeyHandle.
+   * If the key with the same name is created, the old one will be removed.
+   * The behavior of using KeyHandler of removed key is undefined.
+   *
+   * @return The handle of the created key.
+   */
+  unique_ptr<KeyHandle>
+  doCreateKey(const Name& identityName, const KeyParams& params) final;
+
+  /**
+   * @brief Delete a key with name @p keyName.
+   *
+   * @throws Error if the deletion fails.
+   */
+  void
+  doDeleteKey(const Name& keyName) final;
+
+  /**
+   * @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
+   * @throws Error if the key cannot be exported, e.g., not enough privilege
+   */
+  ConstBufferPtr
+  doExportKey(const Name& keyName, const char* pw, size_t pwLen) final;
+
+  /**
+   * @brief Import a private key in encrypted PKCS #8 format
+   *
+   * @param keyName The name of imported private key
+   * @param buf Pointer to the key in encrypted PKCS #8 format
+   * @param size The size of the key in encrypted PKCS #8 format
+   * @param pw The password to decrypt the key
+   * @param pwLen The length of password
+   * @throws Error if import fails.
+   */
+  void
+  doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen) final;
+
+private:
+  class Impl;
+  unique_ptr<Impl> m_impl;
+};
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_BACK_END_MEM_HPP
diff --git a/src/security/tpm/back-end-osx.cpp b/src/security/tpm/back-end-osx.cpp
new file mode 100644
index 0000000..d423b10
--- /dev/null
+++ b/src/security/tpm/back-end-osx.cpp
@@ -0,0 +1,514 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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 "back-end-osx.hpp"
+#include "key-handle-osx.hpp"
+#include "helper-osx.hpp"
+#include "../transform/private-key.hpp"
+#include "tpm.hpp"
+
+#include <CoreServices/CoreServices.h>
+#include <Security/Security.h>
+#include <Security/SecRandom.h>
+#include <Security/SecDigestTransform.h>
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+class BackEndOsx::Impl
+{
+public:
+  Impl()
+    : isTerminalMode(false)
+  {
+  }
+
+  /**
+   * @brief Get private key reference with name @p keyName.
+   *
+   * @param keyName
+   * @returns reference to the key
+   */
+  CFReleaser<SecKeychainItemRef>
+  getKey(const Name& keyName)
+  {
+    CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);
+
+    CFReleaser<CFMutableDictionaryRef> attrDict =
+      CFDictionaryCreateMutable(nullptr, 5, &kCFTypeDictionaryKeyCallBacks, nullptr);
+
+    CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
+    CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
+    CFDictionaryAddValue(attrDict.get(), kSecAttrKeyClass, kSecAttrKeyClassPrivate);
+    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());
+    keyItem.retain();
+
+    if (res != errSecSuccess) {
+      if (res == errSecAuthFailed) {
+        BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
+      }
+      BOOST_THROW_EXCEPTION(std::domain_error("Key does not exist"));
+    }
+
+    return keyItem;
+  }
+
+public:
+  SecKeychainRef keyChainRef;
+  bool isTerminalMode;
+};
+
+
+static CFTypeRef
+getAsymKeyType(KeyType keyType)
+{
+  switch (keyType) {
+  case KeyType::RSA:
+    return kSecAttrKeyTypeRSA;
+  case KeyType::EC:
+    return kSecAttrKeyTypeECDSA;
+  default:
+    BOOST_THROW_EXCEPTION(Tpm::Error("Unsupported key type"));
+  }
+}
+
+static CFTypeRef
+getDigestAlgorithm(DigestAlgorithm digestAlgo)
+{
+  switch (digestAlgo) {
+  case DigestAlgorithm::SHA256:
+    return kSecDigestSHA2;
+  default:
+    return 0;
+  }
+}
+
+static long
+getDigestSize(DigestAlgorithm digestAlgo)
+{
+  switch (digestAlgo) {
+  case DigestAlgorithm::SHA256:
+    return 256;
+  default:
+    return -1;
+  }
+}
+
+BackEndOsx::BackEndOsx()
+  : m_impl(new Impl)
+{
+  SecKeychainSetUserInteractionAllowed(!m_impl->isTerminalMode);
+
+  OSStatus res = SecKeychainCopyDefault(&m_impl->keyChainRef);
+
+  if (res == errSecNoDefaultKeychain) { //If no default key chain, create one.
+    BOOST_THROW_EXCEPTION(Error("No default keychain, create one first"));
+  }
+}
+
+BackEndOsx::~BackEndOsx() = default;
+
+void
+BackEndOsx::setTerminalMode(bool isTerminal)
+{
+  m_impl->isTerminalMode = isTerminal;
+  SecKeychainSetUserInteractionAllowed(!isTerminal);
+}
+
+bool
+BackEndOsx::isTerminalMode() const
+{
+  return m_impl->isTerminalMode;
+}
+
+bool
+BackEndOsx::isLocked() const
+{
+  SecKeychainStatus keychainStatus;
+
+  OSStatus res = SecKeychainGetStatus(m_impl->keyChainRef, &keychainStatus);
+  if (res != errSecSuccess)
+    return true;
+  else
+    return ((kSecUnlockStateStatus & keychainStatus) == 0);
+}
+
+bool
+BackEndOsx::unlockTpm(const char* password, size_t passwordLength)
+{
+  // If the default key chain is already unlocked, return immediately.
+  if (!isLocked())
+    return true;
+
+  if (m_impl->isTerminalMode) {
+    // Use the supplied password.
+    SecKeychainUnlock(m_impl->keyChainRef, passwordLength, password, true);
+  }
+  else {
+    // If inTerminal is not set, get the password from GUI.
+    SecKeychainUnlock(m_impl->keyChainRef, 0, nullptr, false);
+  }
+
+  return !isLocked();
+}
+
+ConstBufferPtr
+BackEndOsx::sign(const KeyRefOsx& key, DigestAlgorithm digestAlgorithm,
+                 const uint8_t* buf, size_t size) const
+{
+  CFReleaser<CFDataRef> dataRef = CFDataCreateWithBytesNoCopy(nullptr, buf, size, kCFAllocatorNull);
+
+  CFReleaser<CFErrorRef> error;
+  // C-style cast is used as per Apple convention
+  CFReleaser<SecTransformRef> signer = SecSignTransformCreate(key.get(), &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Fail to create signer"));
+  }
+
+  // Set input
+  SecTransformSetAttribute(signer.get(), kSecTransformInputAttributeName, dataRef.get(), &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Fail to configure input of signer"));
+  }
+
+  // Enable use of padding
+  SecTransformSetAttribute(signer.get(), kSecPaddingKey, kSecPaddingPKCS1Key, &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Fail to configure digest algorithm of signer"));
+  }
+
+  // Set padding type
+  SecTransformSetAttribute(signer.get(), kSecDigestTypeAttribute, getDigestAlgorithm(digestAlgorithm), &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Fail to configure digest algorithm of signer"));
+  }
+
+  // Set digest attribute
+  long digestSize = getDigestSize(digestAlgorithm);
+  CFReleaser<CFNumberRef> cfDigestSize = CFNumberCreate(nullptr, kCFNumberLongType, &digestSize);
+  SecTransformSetAttribute(signer.get(),
+                           kSecDigestLengthAttribute,
+                           cfDigestSize.get(),
+                           &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(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 != nullptr) {
+    CFShow(error.get());
+    BOOST_THROW_EXCEPTION(Error("Fail to sign data"));
+  }
+
+  if (signature == nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Signature is NULL!\n"));
+  }
+
+  return make_shared<Buffer>(CFDataGetBytePtr(signature.get()), CFDataGetLength(signature.get()));
+}
+
+ConstBufferPtr
+BackEndOsx::decrypt(const KeyRefOsx& key, const uint8_t* cipherText, size_t cipherSize) const
+{
+  CFReleaser<CFDataRef> dataRef = CFDataCreateWithBytesNoCopy(nullptr, cipherText, cipherSize, kCFAllocatorNull);
+
+  CFReleaser<CFErrorRef> error;
+  CFReleaser<SecTransformRef> decryptor = SecDecryptTransformCreate(key.get(), &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Fail to create decrypt"));
+  }
+
+  SecTransformSetAttribute(decryptor.get(), kSecTransformInputAttributeName, dataRef.get(), &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Fail to configure decrypt"));
+  }
+
+  SecTransformSetAttribute(decryptor.get(), kSecPaddingKey, kSecPaddingOAEPKey, &error.get());
+  if (error != nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Fail to configure decrypt #2"));
+  }
+
+  CFReleaser<CFDataRef> output = (CFDataRef)SecTransformExecute(decryptor.get(), &error.get());
+  if (error != nullptr) {
+    // CFShow(error);
+    BOOST_THROW_EXCEPTION(Error("Fail to decrypt data"));
+  }
+
+  if (output == nullptr) {
+    BOOST_THROW_EXCEPTION(Error("Output is NULL!\n"));
+  }
+  return make_shared<Buffer>(CFDataGetBytePtr(output.get()), CFDataGetLength(output.get()));
+}
+
+ConstBufferPtr
+BackEndOsx::derivePublicKey(const KeyRefOsx& key) const
+{
+  CFReleaser<CFDataRef> exportedKey;
+  OSStatus res = SecItemExport(key.get(),           // secItemOrArray
+                               kSecFormatOpenSSL,   // outputFormat
+                               0,                   // flags
+                               nullptr,             // keyParams
+                               &exportedKey.get()); // exportedData
+
+  if (res != errSecSuccess) {
+    if (res == errSecAuthFailed) {
+      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Fail to export private key"));
+    }
+  }
+
+  transform::PrivateKey privateKey;
+  privateKey.loadPkcs1(CFDataGetBytePtr(exportedKey.get()), CFDataGetLength(exportedKey.get()));
+  return privateKey.derivePublicKey();
+}
+
+bool
+BackEndOsx::doHasKey(const Name& keyName) const
+{
+  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);
+
+  CFReleaser<CFMutableDictionaryRef> attrDict =
+    CFDictionaryCreateMutable(nullptr, 4, &kCFTypeDictionaryKeyCallBacks, nullptr);
+
+  CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
+  CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
+  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());
+  itemRef.retain();
+
+  return (res == errSecSuccess);
+}
+
+unique_ptr<KeyHandle>
+BackEndOsx::doGetKeyHandle(const Name& keyName) const
+{
+  CFReleaser<SecKeychainItemRef> keyItem;
+  try {
+    keyItem = m_impl->getKey(keyName);
+  }
+  catch (const std::domain_error&) {
+    return nullptr;
+  }
+
+  return make_unique<KeyHandleOsx>(*this, (SecKeyRef)keyItem.get());
+}
+
+unique_ptr<KeyHandle>
+BackEndOsx::doCreateKey(const Name& identityName, const KeyParams& params)
+{
+  KeyType keyType = params.getKeyType();
+  uint32_t keySize;
+  switch (keyType) {
+    case KeyType::RSA: {
+      const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
+      keySize = rsaParams.getKeySize();
+      break;
+    }
+    case KeyType::EC: {
+      const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params);
+      keySize = ecdsaParams.getKeySize();
+      break;
+    }
+    default: {
+      BOOST_THROW_EXCEPTION(Tpm::Error("Fail to create a key pair: Unsupported key type"));
+    }
+  }
+  CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(nullptr, kCFNumberIntType, &keySize);
+
+  CFReleaser<CFMutableDictionaryRef> attrDict =
+    CFDictionaryCreateMutable(nullptr, 2, &kCFTypeDictionaryKeyCallBacks, nullptr);
+  CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, getAsymKeyType(keyType));
+  CFDictionaryAddValue(attrDict.get(), kSecAttrKeySizeInBits, cfKeySize.get());
+
+  KeyRefOsx publicKey, privateKey;
+  // C-style cast is used as per Apple convention
+  OSStatus res = SecKeyGeneratePair((CFDictionaryRef)attrDict.get(), &publicKey.get(), &privateKey.get());
+
+  BOOST_ASSERT(privateKey != nullptr);
+
+  publicKey.retain();
+  privateKey.retain();
+
+  BOOST_ASSERT(privateKey != nullptr);
+
+  if (res != errSecSuccess) {
+    if (res == errSecAuthFailed) {
+      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Fail to create a key pair"));
+    }
+  }
+
+  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleOsx>(*this, privateKey.get());
+  setKeyName(*keyHandle, identityName, params);
+
+  SecKeychainAttribute attrs[1]; // maximum number of attributes
+  SecKeychainAttributeList attrList = { 0, attrs };
+  std::string keyUri = keyHandle->getKeyName().toUri();
+  {
+    attrs[attrList.count].tag = kSecKeyPrintName;
+    attrs[attrList.count].length = keyUri.size();
+    attrs[attrList.count].data = const_cast<char*>(keyUri.data());
+    attrList.count++;
+  }
+
+  SecKeychainItemModifyAttributesAndData((SecKeychainItemRef)privateKey.get(), &attrList, 0, nullptr);
+  SecKeychainItemModifyAttributesAndData((SecKeychainItemRef)publicKey.get(), &attrList, 0, nullptr);
+
+  return keyHandle;
+}
+
+void
+BackEndOsx::doDeleteKey(const Name& keyName)
+{
+  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);
+
+  CFReleaser<CFMutableDictionaryRef> searchDict =
+    CFDictionaryCreateMutable(nullptr, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+  CFDictionaryAddValue(searchDict.get(), kSecClass, kSecClassKey);
+  CFDictionaryAddValue(searchDict.get(), kSecAttrLabel, keyLabel.get());
+  CFDictionaryAddValue(searchDict.get(), kSecMatchLimit, kSecMatchLimitAll);
+  OSStatus res = SecItemDelete(searchDict.get());
+
+  if (res != errSecSuccess) {
+    if (res == errSecAuthFailed) {
+      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
+    }
+    else if (res != errSecItemNotFound) {
+      BOOST_THROW_EXCEPTION(Error("Fail to delete a key pair"));
+    }
+  }
+}
+
+ConstBufferPtr
+BackEndOsx::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
+{
+  CFReleaser<SecKeychainItemRef> privateKey;
+
+  try {
+    privateKey = m_impl->getKey(keyName);
+  }
+  catch (const std::domain_error&) {
+    BOOST_THROW_EXCEPTION(Tpm::Error("Private key does not exist in OSX Keychain"));
+  }
+
+  CFReleaser<CFDataRef> exportedKey;
+  SecItemImportExportKeyParameters keyParams;
+  memset(&keyParams, 0, sizeof(keyParams));
+  CFReleaser<CFStringRef> passphrase =
+    CFStringCreateWithBytes(0, reinterpret_cast<const uint8_t*>(pw), pwLen, kCFStringEncodingUTF8, false);
+  keyParams.passphrase = passphrase.get();
+  OSStatus res = SecItemExport(privateKey.get(),       // secItemOrArray
+                               kSecFormatWrappedPKCS8, // outputFormat
+                               0,                      // flags
+                               &keyParams,             // keyParams
+                               &exportedKey.get());    // exportedData
+
+  if (res != errSecSuccess) {
+    if (res == errSecAuthFailed) {
+      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Fail to export private key"));
+    }
+  }
+
+  return make_shared<Buffer>(CFDataGetBytePtr(exportedKey.get()), CFDataGetLength(exportedKey.get()));
+}
+
+void
+BackEndOsx::doImportKey(const Name& keyName, const uint8_t* buf, size_t size,
+                        const char* pw, size_t pwLen)
+{
+  CFReleaser<CFDataRef> importedKey = CFDataCreateWithBytesNoCopy(nullptr, buf, size, kCFAllocatorNull);
+
+  SecExternalFormat externalFormat = kSecFormatWrappedPKCS8;
+  SecExternalItemType externalType = kSecItemTypePrivateKey;
+
+  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);
+  CFReleaser<CFStringRef> passphrase =
+    CFStringCreateWithBytes(nullptr, reinterpret_cast<const uint8_t*>(pw), pwLen, kCFStringEncodingUTF8, false);
+  CFReleaser<SecAccessRef> access;
+  SecAccessCreate(keyLabel.get(), nullptr, &access.get());
+
+  CFArrayRef attributes = nullptr;
+
+  const SecItemImportExportKeyParameters keyParams{
+    SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION, // version
+    0, // flags
+    passphrase.get(), // passphrase
+    nullptr, // alert title
+    nullptr, // alert prompt
+    access.get(), // access ref
+    nullptr, // key usage
+    attributes // key attributes
+  };
+
+  CFReleaser<CFArrayRef> outItems;
+  OSStatus res = SecItemImport(importedKey.get(),   // importedData
+                               nullptr,             // fileNameOrExtension
+                               &externalFormat,     // inputFormat
+                               &externalType,       // itemType
+                               0,                   // flags
+                               &keyParams,          // keyParams
+                               m_impl->keyChainRef, // importKeychain
+                               &outItems.get());    // outItems
+
+  if (res != errSecSuccess) {
+    if (res == errSecAuthFailed) {
+      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Cannot import the private key"));
+    }
+  }
+
+  // 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 };
+  std::string keyUri = keyName.toUri();
+  {
+    attrs[attrList.count].tag = kSecKeyPrintName;
+    attrs[attrList.count].length = keyUri.size();
+    attrs[attrList.count].data = const_cast<char*>(keyUri.c_str());
+    attrList.count++;
+  }
+
+  res = SecKeychainItemModifyAttributesAndData(privateKey, &attrList, 0, nullptr);
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/back-end-osx.hpp b/src/security/tpm/back-end-osx.hpp
new file mode 100644
index 0000000..0fcd49f
--- /dev/null
+++ b/src/security/tpm/back-end-osx.hpp
@@ -0,0 +1,162 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_BACK_END_OSX_HPP
+#define NDN_SECURITY_TPM_BACK_END_OSX_HPP
+
+#include "back-end.hpp"
+#include "helper-osx.hpp"
+
+#ifndef NDN_CXX_HAVE_OSX_SECURITY
+#error "This file should not be compiled ..."
+#endif
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+/**
+ * @brief The back-end implementation of TPM based on OS X KeyChain service.
+ */
+class BackEndOsx : public BackEnd
+{
+public:
+  class Error : public BackEnd::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : BackEnd::Error(what)
+    {
+    }
+  };
+
+public:
+  BackEndOsx();
+
+  ~BackEndOsx() override;
+
+public: // management
+  /**
+   * @brief Set the terminal mode of TPM.
+   *
+   * In terminal mode, TPM will not ask user permission from GUI.
+   */
+  void
+  setTerminalMode(bool isTerminal);
+
+  /**
+   * @brief Check if TPM is in terminal mode
+   */
+  bool
+  isTerminalMode() const;
+
+  /**
+   * @return True if TPM is locked, otherwise false
+   */
+  bool
+  isLocked() const;
+
+  /**
+   * @brief Unlock TPM
+   *
+   * @param password       The password to unlock TPM
+   * @param passwordLength The password size.
+   */
+  bool
+  unlockTpm(const char* password = nullptr, size_t passwordLength = 0);
+
+public: // crypto transformation
+  /**
+   * @brief Sign @p buf with @p key using @p digestAlgorithm.
+   */
+  ConstBufferPtr
+  sign(const KeyRefOsx& key, DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const;
+
+  ConstBufferPtr
+  decrypt(const KeyRefOsx& key, const uint8_t* cipherText, size_t cipherSize) const;
+
+  ConstBufferPtr
+  derivePublicKey(const KeyRefOsx& key) const;
+
+private: // inherited from tpm::BackEnd
+
+  /**
+   * @return True if a key with name @p keyName exists in TPM.
+   */
+  bool
+  doHasKey(const Name& keyName) const final;
+
+  /**
+   * @return The handle of a key with name @p keyName, or nullptr if the key does not exist
+   */
+  unique_ptr<KeyHandle>
+  doGetKeyHandle(const Name& keyName) const final;
+
+  /**
+   * @brief Create key for @p identityName according to @p params.
+   *
+   * The created key is named as: /<identityName>/[keyId]/KEY
+   * The key name is set in the returned KeyHandle.
+   *
+   * @return The handle of the created key.
+   */
+  unique_ptr<KeyHandle>
+  doCreateKey(const Name& identityName, const KeyParams& params) final;
+
+  /**
+   * @brief Delete a key with name @p keyName.
+   *
+   * @throws Error if the deletion fails.
+   */
+  void
+  doDeleteKey(const Name& keyName) final;
+
+  /**
+   * @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
+   * @throws Error if the key cannot be exported, e.g., not enough privilege
+   */
+  ConstBufferPtr
+  doExportKey(const Name& keyName, const char* pw, size_t pwLen) final;
+
+  /**
+   * @brief Import a private key in encrypted PKCS #8 format
+   *
+   * @param keyName The name of imported private key
+   * @param buf Pointer to the key in encrypted PKCS #8 format
+   * @param size The size of the key in encrypted PKCS #8 format
+   * @param pw The password to decrypt the private key
+   * @param pwLen The length of the password
+   * @throws Error if import fails
+   */
+  void
+  doImportKey(const Name& keyName, const uint8_t* buf, size_t size, const char* pw, size_t pwLen) final;
+
+private:
+  class Impl;
+  unique_ptr<Impl> m_impl;
+};
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_BACK_END_OSX_HPP
diff --git a/src/security/tpm/back-end.cpp b/src/security/tpm/back-end.cpp
new file mode 100644
index 0000000..18df659
--- /dev/null
+++ b/src/security/tpm/back-end.cpp
@@ -0,0 +1,138 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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 "back-end.hpp"
+#include "key-handle.hpp"
+#include "tpm.hpp"
+#include "../transform.hpp"
+#include "../../encoding/buffer-stream.hpp"
+#include "../../util/random.hpp"
+#include "../pib/key.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+BackEnd::~BackEnd() = default;
+
+bool
+BackEnd::hasKey(const Name& keyName) const
+{
+  return doHasKey(keyName);
+}
+
+unique_ptr<KeyHandle>
+BackEnd::getKeyHandle(const Name& keyName) const
+{
+  return doGetKeyHandle(keyName);
+}
+
+unique_ptr<KeyHandle>
+BackEnd::createKey(const Name& identity, const KeyParams& params)
+{
+  // key name checking
+  switch (params.getKeyIdType()) {
+    case KeyIdType::USER_SPECIFIED: { // keyId is pre-set.
+      Name keyName = v2::constructKeyName(identity, params.getKeyId());
+      if (hasKey(keyName)) {
+        BOOST_THROW_EXCEPTION(Tpm::Error("Key `" + keyName.toUri() + "` already exists"));
+      }
+      break;
+    }
+    case KeyIdType::SHA256: {
+      // KeyName will be assigned in setKeyName after key is generated
+      break;
+    }
+    case KeyIdType::RANDOM: {
+      Name keyName;
+      name::Component keyId;
+      do {
+        keyId = name::Component::fromNumber(random::generateSecureWord64());
+        keyName = v2::constructKeyName(identity, params.getKeyId());
+      } while (hasKey(keyName));
+
+      const_cast<KeyParams&>(params).setKeyId(keyId);
+      break;
+    }
+    default: {
+      BOOST_THROW_EXCEPTION(Error("Unsupported key id type"));
+    }
+  }
+
+  return doCreateKey(identity, params);
+}
+
+void
+BackEnd::deleteKey(const Name& keyName)
+{
+  doDeleteKey(keyName);
+}
+
+ConstBufferPtr
+BackEnd::exportKey(const Name& keyName, const char* pw, size_t pwLen)
+{
+  if (!hasKey(keyName)) {
+    BOOST_THROW_EXCEPTION(Error("Key `" + keyName.toUri() + "` does not exist"));
+  }
+  return doExportKey(keyName, pw, pwLen);
+}
+
+void
+BackEnd::importKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen)
+{
+  if (hasKey(keyName)) {
+    BOOST_THROW_EXCEPTION(Error("Key `" + keyName.toUri() + "` already exists"));
+  }
+  doImportKey(keyName, pkcs8, pkcs8Len, pw, pwLen);
+}
+
+void
+BackEnd::setKeyName(KeyHandle& keyHandle, const Name& identity, const KeyParams& params)
+{
+  name::Component keyId;
+  switch (params.getKeyIdType()) {
+    case KeyIdType::USER_SPECIFIED:
+      keyId = params.getKeyId();
+      break;
+    case KeyIdType::SHA256: {
+      using namespace transform;
+
+      OBufferStream os;
+      bufferSource(*keyHandle.derivePublicKey()) >> digestFilter() >> streamSink(os);
+      keyId = name::Component(os.buf());
+      break;
+    }
+    case KeyIdType::RANDOM: {
+      BOOST_ASSERT(!params.getKeyId().empty());
+      keyId = params.getKeyId();
+      break;
+    }
+    default: {
+      BOOST_ASSERT(false);
+    }
+  }
+
+  keyHandle.setKeyName(v2::constructKeyName(identity, keyId));
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/back-end.hpp b/src/security/tpm/back-end.hpp
new file mode 100644
index 0000000..749b53d
--- /dev/null
+++ b/src/security/tpm/back-end.hpp
@@ -0,0 +1,182 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_BACK_END_HPP
+#define NDN_SECURITY_TPM_BACK_END_HPP
+
+#include "../../common.hpp"
+#include "../../name.hpp"
+#include "../../encoding/buffer.hpp"
+#include "../key-params.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+class KeyHandle;
+
+/**
+ * @brief Abstraction of Tpm back-end.
+ *
+ * This class provides KeyHandle to the front-end and other TPM management operations.
+ */
+class BackEnd : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  virtual
+  ~BackEnd();
+
+public: // key management
+  /**
+   * @return True if a key with name @p keyName exists in TPM.
+   */
+  bool
+  hasKey(const Name& keyName) const;
+
+  /**
+   * @return The handle of a key with name @p keyName, or nullptr if the key does not exist.
+   *
+   * Calling getKeyHandle multiple times with the same keyName will return different KeyHandle
+   * objects that all refer to the same key.
+   */
+  unique_ptr<KeyHandle>
+  getKeyHandle(const Name& keyName) const;
+
+  /**
+   * @brief Create key for @p identity according to @p params.
+   *
+   * The key name is set in the returned KeyHandle.
+   *
+   * @return The handle of the created key.
+   * @throws Tpm::Error if @p params is invalid
+   * @throws Error if the key cannot be created.
+   */
+  unique_ptr<KeyHandle>
+  createKey(const Name& identity, const KeyParams& params);
+
+  /**
+   * @brief Delete a key with name @p keyName.
+   *
+   * Continuing to use existing KeyHandles on a deleted key results in undefined behavior.
+   *
+   * @throws Error if the deletion fails.
+   */
+  void
+  deleteKey(const Name& keyName);
+
+  /**
+   * @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
+   * @throws Error if the key does not exist
+   * @throws Error if the key cannot be exported, e.g., insufficient privilege
+   */
+  ConstBufferPtr
+  exportKey(const Name& keyName, const char* pw, size_t pwLen);
+
+  /**
+   * @brief Import a private key in encrypted PKCS #8 format
+   *
+   * @param keyName The name of imported private key
+   * @param pkcs8 Pointer to the key in encrypted PKCS #8 format
+   * @param pkcs8Len The size of the key in encrypted PKCS #8 format
+   * @param pw The password to decrypt the private key
+   * @param pwLen The length of the password
+   * @throws Error if import fails.
+   */
+  void
+  importKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen);
+
+protected: // static helper method
+  /**
+   * @brief Set the key name in @p keyHandle according to @p identity and @p params
+   */
+  static void
+  setKeyName(KeyHandle& keyHandle, const Name& identity, const KeyParams& params);
+
+private: // pure virtual methods
+  /**
+   * @return True if a key with name @p keyName exists in TPM.
+   */
+  virtual bool
+  doHasKey(const Name& keyName) const = 0;
+
+  /**
+   * @return The handle of a key with name @p keyName, or nullptr if the key does not exist
+   */
+  virtual unique_ptr<KeyHandle>
+  doGetKeyHandle(const Name& keyName) const = 0;
+
+  /**
+   * @brief Create key for @p identityName according to @p params.
+   *
+   * The created key is named as: /<identityName>/[keyId]/KEY
+   * The key name is set in the returned KeyHandle.
+   *
+   * @return The handle of the created key.
+   * @throws Error when key cannot be created.
+   */
+  virtual unique_ptr<KeyHandle>
+  doCreateKey(const Name& identity, const KeyParams& params) = 0;
+
+  /**
+   * @brief Delete a key with name @p keyName.
+   *
+   * @throws Error if the deletion fails.
+   */
+  virtual void
+  doDeleteKey(const Name& keyName) = 0;
+
+  /**
+   * @return A private key with name @p keyName in encrypted PKCS #8 format using password @p pw
+   * @throws Error if the key cannot be exported, e.g., insufficient privilege
+   */
+  virtual ConstBufferPtr
+  doExportKey(const Name& keyName, const char* pw, size_t pwLen) = 0;
+
+  /**
+   * @brief Import a private key in encrypted PKCS #8 format using @p password
+   *
+   * @param keyName The name of imported private key
+   * @param pkcs8 Pointer to the key in PKCS #8 format
+   * @param pkcs8Len The size of the key in PKCS #8 format
+   * @param pw The password to decrypt the private key
+   * @param pwLen The length of the password
+   * @throws Error if import fails.
+   */
+  virtual void
+  doImportKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen) = 0;
+};
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_BACK_END_HPP
diff --git a/src/security/tpm/helper-osx.hpp b/src/security/tpm/helper-osx.hpp
new file mode 100644
index 0000000..2e7d827
--- /dev/null
+++ b/src/security/tpm/helper-osx.hpp
@@ -0,0 +1,154 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_HELPER_OSX_HPP
+#define NDN_SECURITY_TPM_HELPER_OSX_HPP
+
+#include "../../common.hpp"
+
+#ifndef NDN_CXX_HAVE_OSX_SECURITY
+#error "This file should not be included ..."
+#endif
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+/**
+ * @brief Helper class to wrap CoreFoundation object pointers
+ *
+ * The class is similar in spirit to shared_ptr, but uses CoreFoundation
+ * mechanisms to retain/release object.
+ *
+ * Original implementation by Christopher Hunt and it was borrowed from
+ * http://www.cocoabuilder.com/archive/cocoa/130776-auto-cfrelease-and.html
+ */
+template<class T>
+class CFReleaser
+{
+public: // Construction/destruction
+  CFReleaser()
+    : m_typeRef(nullptr)
+  {
+  }
+
+  CFReleaser(const T& typeRef)
+    : m_typeRef(typeRef)
+  {
+  }
+
+  CFReleaser(const CFReleaser& inReleaser)
+    : m_typeRef(nullptr)
+  {
+    retain(inReleaser.m_typeRef);
+  }
+
+  CFReleaser&
+  operator=(const T& typeRef)
+  {
+    if (typeRef != m_typeRef) {
+      release();
+      m_typeRef = typeRef;
+    }
+    return *this;
+  }
+
+  CFReleaser&
+  operator=(const CFReleaser& inReleaser)
+  {
+    retain(inReleaser.m_typeRef);
+    return *this;
+  }
+
+  ~CFReleaser()
+  {
+    release();
+  }
+
+public: // Access
+  const T&
+  get() const
+  {
+    return m_typeRef;
+  }
+
+  T&
+  get()
+  {
+    return m_typeRef;
+  }
+
+  bool
+  operator==(const std::nullptr_t&)
+  {
+    return m_typeRef == nullptr;
+  }
+
+  bool
+  operator!=(const std::nullptr_t&)
+  {
+    return m_typeRef != nullptr;
+  }
+
+  ///////////////////
+  // Miscellaneous //
+
+  void
+  retain(const T& typeRef)
+  {
+    if (typeRef != nullptr) {
+      CFRetain(typeRef);
+    }
+    release();
+    m_typeRef = typeRef;
+  }
+
+  void
+  retain()
+  {
+    T typeRef = m_typeRef;
+    m_typeRef = nullptr;
+    retain(typeRef);
+  }
+
+  void
+  release()
+  {
+    if (m_typeRef != nullptr) {
+      CFRelease(m_typeRef);
+      m_typeRef = nullptr;
+    }
+  };
+
+private:
+  T m_typeRef;
+};
+
+typedef CFReleaser<SecKeyRef> KeyRefOsx;
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_HELPER_OSX_HPP
diff --git a/src/security/tpm/key-handle-mem.cpp b/src/security/tpm/key-handle-mem.cpp
new file mode 100644
index 0000000..00f5b21
--- /dev/null
+++ b/src/security/tpm/key-handle-mem.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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-handle-mem.hpp"
+#include "../../encoding/buffer-stream.hpp"
+#include "../transform.hpp"
+#include "../transform/private-key.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+using transform::PrivateKey;
+
+KeyHandleMem::KeyHandleMem(shared_ptr<PrivateKey> key)
+  : m_key(key)
+{
+  BOOST_ASSERT(key != nullptr);
+}
+
+ConstBufferPtr
+KeyHandleMem::doSign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const
+{
+  switch (digestAlgorithm) {
+    case DigestAlgorithm::SHA256: {
+      using namespace transform;
+
+      OBufferStream sigOs;
+      bufferSource(buf, size) >> signerFilter(digestAlgorithm, *m_key) >> streamSink(sigOs);
+      return sigOs.buf();
+    }
+    default:
+      return nullptr;
+  }
+}
+
+ConstBufferPtr
+KeyHandleMem::doDecrypt(const uint8_t* cipherText, size_t cipherTextLen) const
+{
+  return m_key->decrypt(cipherText, cipherTextLen);
+}
+
+ConstBufferPtr
+KeyHandleMem::doDerivePublicKey() const
+{
+  return m_key->derivePublicKey();
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/key-handle-mem.hpp b/src/security/tpm/key-handle-mem.hpp
new file mode 100644
index 0000000..006c4ec
--- /dev/null
+++ b/src/security/tpm/key-handle-mem.hpp
@@ -0,0 +1,63 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_KEY_HANDLE_MEM_HPP
+#define NDN_SECURITY_TPM_KEY_HANDLE_MEM_HPP
+
+#include "key-handle.hpp"
+
+namespace ndn {
+namespace security {
+
+namespace transform {
+class PrivateKey;
+} // namespace transform
+
+namespace tpm {
+
+/**
+ * @brief A TPM key handle that keeps the private key in memory
+ */
+class KeyHandleMem : public KeyHandle
+{
+public:
+  explicit
+  KeyHandleMem(shared_ptr<transform::PrivateKey> key);
+
+private:
+  ConstBufferPtr
+  doSign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const final;
+
+  ConstBufferPtr
+  doDecrypt(const uint8_t* cipherText, size_t cipherTextLen) const final;
+
+  ConstBufferPtr
+  doDerivePublicKey() const final;
+
+private:
+  shared_ptr<transform::PrivateKey> m_key;
+};
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_KEY_HANDLE_MEM_HPP
diff --git a/src/security/tpm/key-handle-osx.cpp b/src/security/tpm/key-handle-osx.cpp
new file mode 100644
index 0000000..518a673
--- /dev/null
+++ b/src/security/tpm/key-handle-osx.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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-handle-osx.hpp"
+#include "back-end-osx.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+KeyHandleOsx::KeyHandleOsx(const BackEndOsx& impl, const KeyRefOsx& key)
+  : m_impl(impl)
+  , m_key(key)
+{
+  if (m_key.get() == 0)
+    BOOST_THROW_EXCEPTION(Error("key is not set"));
+}
+
+ConstBufferPtr
+KeyHandleOsx::doSign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const
+{
+  return m_impl.sign(m_key, digestAlgorithm, buf, size);
+}
+
+ConstBufferPtr
+KeyHandleOsx::doDecrypt(const uint8_t* cipherText, size_t cipherTextLen) const
+{
+  return m_impl.decrypt(m_key, cipherText, cipherTextLen);
+}
+
+ConstBufferPtr
+KeyHandleOsx::doDerivePublicKey() const
+{
+  return m_impl.derivePublicKey(m_key);
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/key-handle-osx.hpp b/src/security/tpm/key-handle-osx.hpp
new file mode 100644
index 0000000..4337f0d
--- /dev/null
+++ b/src/security/tpm/key-handle-osx.hpp
@@ -0,0 +1,76 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_KEY_HANDLE_OSX_HPP
+#define NDN_SECURITY_TPM_KEY_HANDLE_OSX_HPP
+
+#include "key-handle.hpp"
+#include "helper-osx.hpp"
+
+#ifndef NDN_CXX_HAVE_OSX_SECURITY
+#error "This file should not be compiled ..."
+#endif
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+class BackEndOsx;
+
+/**
+ * @brief Abstraction of TPM key handle used by the TPM based on OS X Keychain Service.
+ */
+class KeyHandleOsx : public KeyHandle
+{
+public:
+  class Error : public KeyHandle::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : KeyHandle::Error(what)
+    {
+    }
+  };
+
+public:
+  KeyHandleOsx(const BackEndOsx& impl, const KeyRefOsx& key);
+
+private:
+  ConstBufferPtr
+  doSign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const final;
+
+  ConstBufferPtr
+  doDecrypt(const uint8_t* cipherText, size_t cipherTextLen) const final;
+
+  ConstBufferPtr
+  doDerivePublicKey() const final;
+
+private:
+  const BackEndOsx& m_impl;
+  KeyRefOsx m_key;
+};
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_KEY_HANDLE_OSX_HPP
diff --git a/src/security/tpm/key-handle.cpp b/src/security/tpm/key-handle.cpp
new file mode 100644
index 0000000..70553b4
--- /dev/null
+++ b/src/security/tpm/key-handle.cpp
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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-handle.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+KeyHandle::~KeyHandle() = default;
+
+ConstBufferPtr
+KeyHandle::sign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const
+{
+  return doSign(digestAlgorithm, buf, size);
+}
+
+ConstBufferPtr
+KeyHandle::decrypt(const uint8_t* cipherText, size_t cipherTextLen) const
+{
+  return doDecrypt(cipherText, cipherTextLen);
+}
+
+ConstBufferPtr
+KeyHandle::derivePublicKey() const
+{
+  return doDerivePublicKey();
+}
+
+void
+KeyHandle::setKeyName(const Name& keyName)
+{
+  m_keyName = keyName;
+}
+
+Name
+KeyHandle::getKeyName() const
+{
+  return m_keyName;
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/key-handle.hpp b/src/security/tpm/key-handle.hpp
new file mode 100644
index 0000000..d6faf4d
--- /dev/null
+++ b/src/security/tpm/key-handle.hpp
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_KEY_HANDLE_HPP
+#define NDN_SECURITY_TPM_KEY_HANDLE_HPP
+
+#include "../../common.hpp"
+#include "../../name.hpp"
+#include "../security-common.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+/**
+ * @brief Abstraction of TPM key handle.
+ *
+ * Handle provides an interface to perform crypto operations with a key in TPM.
+ */
+class KeyHandle : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  virtual
+  ~KeyHandle();
+
+  /**
+   * @return a digital signature created on @p buf using this key with @p digestAlgorithm.
+   */
+  ConstBufferPtr
+  sign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const;
+
+  /**
+   * @return plain text content decrypted from @p cipherText using this key.
+   */
+  ConstBufferPtr
+  decrypt(const uint8_t* cipherText, size_t cipherTextLen) const;
+
+  /**
+   * @return the PCKS#8 encoded public key bits derived from this key.
+   */
+  ConstBufferPtr
+  derivePublicKey() const;
+
+  void
+  setKeyName(const Name& keyName);
+
+  Name
+  getKeyName() const;
+
+private:
+  virtual ConstBufferPtr
+  doSign(DigestAlgorithm digestAlgorithm, const uint8_t* buf, size_t size) const = 0;
+
+  virtual ConstBufferPtr
+  doDecrypt(const uint8_t* cipherText, size_t cipherTextLen) const = 0;
+
+  virtual ConstBufferPtr
+  doDerivePublicKey() const = 0;
+
+private:
+  Name m_keyName;
+};
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_KEY_HANDLE_HPP
diff --git a/src/security/tpm/tpm.cpp b/src/security/tpm/tpm.cpp
new file mode 100644
index 0000000..234c48d
--- /dev/null
+++ b/src/security/tpm/tpm.cpp
@@ -0,0 +1,150 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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 "tpm.hpp"
+#include "back-end.hpp"
+#include "../../encoding/buffer-stream.hpp"
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+Tpm::Tpm(const std::string& scheme, const std::string& location, unique_ptr<BackEnd> backEnd)
+  : m_scheme(scheme)
+  , m_location(location)
+  , m_backEnd(std::move(backEnd))
+{
+}
+
+Tpm::~Tpm() = default;
+
+std::string
+Tpm::getTpmLocator() const
+{
+  return m_scheme + ":" + m_location;
+}
+
+bool
+Tpm::hasKey(const Name& keyName) const
+{
+  return m_backEnd->hasKey(keyName);
+}
+
+Name
+Tpm::createKey(const Name& identityName, const KeyParams& params)
+{
+  switch (params.getKeyType()) {
+    case KeyType::RSA:
+    case KeyType::EC: {
+      unique_ptr<KeyHandle> keyHandle = m_backEnd->createKey(identityName, params);
+      Name keyName = keyHandle->getKeyName();
+      m_keys[keyName] = std::move(keyHandle);
+      return keyName;
+    }
+    default: {
+      BOOST_THROW_EXCEPTION(Error("Fail to create a key pair: Unsupported key type"));
+    }
+  }
+}
+
+void
+Tpm::deleteKey(const Name& keyName)
+{
+  auto it = m_keys.find(keyName);
+  if (it != m_keys.end())
+    m_keys.erase(it);
+
+  m_backEnd->deleteKey(keyName);
+}
+
+ConstBufferPtr
+Tpm::getPublicKey(const Name& keyName) const
+{
+  const KeyHandle* key = findKey(keyName);
+
+  if (key == nullptr)
+    return nullptr;
+  else
+    return key->derivePublicKey();
+}
+
+ConstBufferPtr
+Tpm::sign(const uint8_t* buf, size_t size, const Name& keyName, DigestAlgorithm digestAlgorithm) const
+{
+  const KeyHandle* key = findKey(keyName);
+
+  if (key == nullptr)
+    return nullptr;
+  else
+    return key->sign(digestAlgorithm, buf, size);
+}
+
+ConstBufferPtr
+Tpm::decrypt(const uint8_t* buf, size_t size, const Name& keyName) const
+{
+  const KeyHandle* key = findKey(keyName);
+
+  if (key == nullptr)
+    return nullptr;
+  else
+    return key->decrypt(buf, size);
+}
+
+ConstBufferPtr
+Tpm::exportPrivateKey(const Name& keyName, const char* pw, size_t pwLen)
+{
+  return m_backEnd->exportKey(keyName, pw, pwLen);
+}
+
+bool
+Tpm::importPrivateKey(const Name& keyName, const uint8_t* pkcs8, size_t pkcs8Len, const char* pw, size_t pwLen)
+{
+  try {
+    m_backEnd->importKey(keyName, pkcs8, pkcs8Len, pw, pwLen);
+  }
+  catch (const BackEnd::Error&) {
+    return false;
+  }
+  return true;
+}
+
+const KeyHandle*
+Tpm::findKey(const Name& keyName) const
+{
+  auto it = m_keys.find(keyName);
+
+  if (it != m_keys.end())
+    return it->second.get();
+
+  unique_ptr<KeyHandle> handle = m_backEnd->getKeyHandle(keyName);
+
+  if (handle != nullptr) {
+    KeyHandle* key = handle.get();
+    m_keys[keyName] = std::move(handle);
+    return key;
+  }
+
+  return nullptr;
+}
+
+} // namespace tpm
+} // namespace security
+} // namespace ndn
diff --git a/src/security/tpm/tpm.hpp b/src/security/tpm/tpm.hpp
new file mode 100644
index 0000000..01b22ae
--- /dev/null
+++ b/src/security/tpm/tpm.hpp
@@ -0,0 +1,207 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 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_TPM_TPM_HPP
+#define NDN_SECURITY_TPM_TPM_HPP
+
+#include "../../common.hpp"
+#include "../security-common.hpp"
+#include "../../name.hpp"
+#include "../key-params.hpp"
+#include "key-handle.hpp"
+#include <unordered_map>
+
+namespace ndn {
+namespace security {
+namespace tpm {
+
+class BackEnd;
+
+/**
+ * @brief represents the front-end of TPM
+ *
+ * The TPM (Trusted Platform Module) stores the private portion of a user's cryptography keys.
+ * The format and location of stored information is indicated by the TpmLocator.
+ * The TPM is designed to work with a PIB (Public Information Base) which stores public keys and
+ * related information such as certificate.
+ *
+ * The TPM also provides functionalities of crypto transformation, such as signing and decryption.
+ *
+ * A TPM consists of a unified front-end interface and a back-end implementation. The front-end
+ * cache the handles of private keys which is provided by the back-end implementation.
+ *
+ * @throw tpm::BackEnd::Error when underlying implementation has non-semantic error.
+ * @throw Tpm::Error when there is an semantic error.
+ */
+class Tpm : noncopyable
+{
+public:
+  friend class KeyChain;
+
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  ~Tpm();
+
+  std::string
+  getTpmLocator() const;
+
+  /**
+   * @brief Check if a private key exist
+   *
+   * @param keyName The key name
+   * @return true if the key exists
+   */
+  bool
+  hasKey(const Name& keyName) const;
+
+  /**
+   * @return The public portion of an asymmetric key with name @p name
+   *         or nullptr if the key does not exist
+   *
+   * The public key is in PKCS#8 format
+   */
+  ConstBufferPtr
+  getPublicKey(const Name& keyName) const;
+
+  /**
+   * @brief Sign blob using key with name @p keyName with digest @p digestAlgorithm.
+   *
+   * @return The signature, or nullptr if the key does not exist
+   */
+  ConstBufferPtr
+  sign(const uint8_t* buf, size_t size, const Name& keyName, DigestAlgorithm digestAlgorithm) const;
+
+  /**
+   * @brief Decrypt blob using key with name @p keyName.
+   *
+   * @return The signature, or nullptr if the key does not exist
+   */
+  ConstBufferPtr
+  decrypt(const uint8_t* buf, size_t size, const Name& keyName) const;
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /*
+   * @brief Create a new TPM instance with the specified @p location
+   *
+   * @param scheme The scheme for the TPM
+   * @param location The location for the TPM
+   * @param impl The back-end implementation
+   */
+  Tpm(const std::string& scheme, const std::string& location, unique_ptr<BackEnd> impl);
+
+  BackEnd*
+  getBackEnd()
+  {
+    return m_backEnd.get();
+  }
+
+  /**
+   * @brief Create key for @p identityName according to @p params.
+   *
+   * The created key is named as: /<identityName>/[keyId]/KEY
+   *
+   * @return the key name
+   * @throws Tpm::Error if the key has already existed or the params is invalid
+   */
+  Name
+  createKey(const Name& identityName, const KeyParams& params);
+
+  /**
+   * @brief Delete a key pair with name @p keyName.
+   */
+  void
+  deleteKey(const Name& keyName);
+
+  /**
+   * @brief Export a private key
+   *
+   * This method will export the private key in encrypted PKCS #8 format if the key exists.
+   *
+   * @param keyName  The private key name
+   * @param pw The password to encrypt the private key
+   * @param pwLen The length of the password
+   * @return The encoded private key wrapper or an empty block if the key cannot be exported.
+   */
+  ConstBufferPtr
+  exportPrivateKey(const Name& keyName, const char* pw, size_t pwLen);
+
+  /**
+   * @brief Import a private key
+   *
+   * @param keyName The private key name
+   * @param pkcs8 The private key wrapper
+   * @param pkcs8Len The length of the private key wrapper
+   * @param pw The password to encrypt the private key
+   * @param pwLen The length of the password
+   * @return false if importing fails
+   */
+  bool
+  importPrivateKey(const Name& keyName,
+                   const uint8_t* pkcs8, size_t pkcs8Len,
+                   const char* pw, size_t pwLen);
+
+  /**
+   * @brief Clear the key cache
+   *
+   * An empty cache can force Tpm to do key lookup in back-end.
+   */
+  void
+  clearKeyCache()
+  {
+    m_keys.clear();
+  }
+
+private:
+
+  /**
+   * @brief Internal KeyHandle lookup
+   *
+   * @return A pointer to the handle of key @p keyName if it exists, otherwise nullptr.
+   */
+  const KeyHandle*
+  findKey(const Name& keyName) const;
+
+private:
+  std::string m_scheme;
+  std::string m_location;
+
+  mutable std::unordered_map<Name, unique_ptr<KeyHandle>> m_keys;
+
+  unique_ptr<BackEnd> m_backEnd;
+};
+
+} // namespace tpm
+
+using tpm::Tpm;
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_SECURITY_TPM_TPM_HPP
