diff --git a/src/encrypted-content.cpp b/src/encrypted-content.cpp
new file mode 100644
index 0000000..0a7c9e1
--- /dev/null
+++ b/src/encrypted-content.cpp
@@ -0,0 +1,162 @@
+#include "encrypted-content.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <ndn-cxx/util/concepts.hpp>
+
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace gep {
+
+BOOST_CONCEPT_ASSERT((boost::EqualityComparable<EncryptedContent>));
+BOOST_CONCEPT_ASSERT((WireEncodable<EncryptedContent>));
+BOOST_CONCEPT_ASSERT((WireDecodable<EncryptedContent>));
+static_assert(std::is_base_of<ndn::tlv::Error, EncryptedContent::Error>::value,
+              "EncryptedContent::Error must inherit from tlv::Error");
+
+EncryptedContent::EncryptedContent()
+  : m_type(-1)
+  , m_hasKeyLocator(false)
+{
+}
+
+EncryptedContent::EncryptedContent(tlv::AlgorithmTypeValue type, const KeyLocator& keyLocator, const ConstBufferPtr& payload)
+  : m_type(type)
+  , m_hasKeyLocator(true)
+  , m_keyLocator(keyLocator)
+  , m_payload(payload)
+{
+}
+
+EncryptedContent::EncryptedContent(const Block& block)
+{
+  wireDecode(block);
+}
+
+void
+EncryptedContent::setAlgorithmType(tlv::AlgorithmTypeValue type)
+{
+  m_wire.reset();
+  m_type = type;
+}
+
+void
+EncryptedContent::setKeyLocator(const KeyLocator& keyLocator)
+{
+  m_wire.reset();
+  m_keyLocator = keyLocator;
+  m_hasKeyLocator = true;
+}
+
+const KeyLocator&
+EncryptedContent::getKeyLocator() const
+{
+  if (m_hasKeyLocator)
+    return m_keyLocator;
+  else
+    throw Error("KeyLocator does not exist");
+}
+
+void
+EncryptedContent::setPayload(const ConstBufferPtr& payload)
+{
+  m_wire.reset();
+  m_payload = payload;
+}
+
+const ConstBufferPtr
+EncryptedContent::getPayload() const
+{
+  return m_payload;
+}
+
+template<encoding::Tag TAG>
+size_t
+EncryptedContent::wireEncode(EncodingImpl<TAG>& block) const
+{
+  size_t totalLength = 0;
+
+  totalLength += block.appendByteArrayBlock(tlv::EncryptedPayload, m_payload->buf(), m_payload->size());
+
+  if (m_type != -1)
+    totalLength += prependNonNegativeIntegerBlock(block, tlv::EncryptionAlgorithm, m_type);
+  else
+    throw Error("EncryptedContent does not have an encryption algorithm");
+
+  if (m_hasKeyLocator)
+    totalLength += m_keyLocator.wireEncode(block);
+  else
+    throw Error("EncryptedContent does not have key locator");
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::EncryptedContent);
+  return totalLength;
+}
+
+const Block&
+EncryptedContent::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+EncryptedContent::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_hasKeyLocator = false;
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::EncryptedContent)
+    throw Error("Unexpected TLV type when decoding Name");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  if (it != m_wire.elements_end() && it->type() == ndn::tlv::KeyLocator) {
+    m_keyLocator.wireDecode(*it);
+    m_hasKeyLocator = true;
+    it++;
+  }
+  else
+    throw Error("EncryptedContent does not have key locator");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::EncryptionAlgorithm) {
+    m_type = readNonNegativeInteger(*it);
+    it++;
+  }
+  else
+    throw Error("EncryptedContent does not have encryption algorithm");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::EncryptedPayload) {
+    m_payload = make_shared<Buffer>(it->value_begin(),it->value_end());
+    it++;
+  }
+  else
+    throw Error("EncryptedContent has missing payload");
+
+  if (it != m_wire.elements_end()) {
+    throw Error("EncryptedContent has extraneous sub-TLVs");
+  }
+}
+
+bool
+EncryptedContent::operator==(const EncryptedContent& rhs) const
+{
+  return (wireEncode() == rhs.wireEncode());
+}
+
+} // namespace gep
+} // namespace ndn
diff --git a/src/encrypted-content.hpp b/src/encrypted-content.hpp
new file mode 100644
index 0000000..2d0203e
--- /dev/null
+++ b/src/encrypted-content.hpp
@@ -0,0 +1,92 @@
+#ifndef NDN_ENCRYPTED_CONTENT_HPP
+#define NDN_ENCRYPTED_CONTENT_HPP
+
+#include <ndn-cxx/encoding/tlv.hpp>
+#include <ndn-cxx/key-locator.hpp>
+#include <list>
+
+#include "tlv.hpp"
+
+namespace ndn {
+namespace gep {
+
+class EncryptedContent
+{
+public:
+  class Error : public ndn::tlv::Error
+  {
+    public:
+      explicit
+      Error(const std::string& what)
+      : ndn::tlv::Error(what)
+      {
+      }
+  };
+
+public:
+  EncryptedContent();
+
+  EncryptedContent(tlv::AlgorithmTypeValue type, const KeyLocator& keyLocator, const ConstBufferPtr& payload);
+
+  explicit
+  EncryptedContent(const Block& block);
+
+  void
+  setAlgorithmType(tlv::AlgorithmTypeValue type);
+
+  int32_t
+  getAlgorithmType() const
+  {
+    return m_type;
+  }
+
+  bool
+  hasKeyLocator() const
+  {
+   return m_hasKeyLocator;
+  }
+
+  void
+  setKeyLocator(const KeyLocator& keyLocator);
+
+  const KeyLocator&
+  getKeyLocator() const;
+
+  void
+  setPayload(const ConstBufferPtr& payload);
+
+  const ConstBufferPtr
+  getPayload() const;
+
+  template<encoding::Tag TAG>
+  size_t
+  wireEncode(EncodingImpl<TAG>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& wire);
+
+public:
+  bool
+  operator==(const EncryptedContent& rhs) const;
+  bool
+  operator!=(const EncryptedContent& rhs) const
+  {
+    return !(*this == rhs);
+  }
+
+private:
+  int32_t m_type;
+  bool m_hasKeyLocator;
+  KeyLocator m_keyLocator;
+  ConstBufferPtr m_payload;
+
+  mutable Block m_wire;
+};
+
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_ENCRYPTED_CONTENT_HPP
diff --git a/src/tlv.hpp b/src/tlv.hpp
new file mode 100644
index 0000000..92f2f4e
--- /dev/null
+++ b/src/tlv.hpp
@@ -0,0 +1,44 @@
+/* -*- 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_GEP_TLV_HPP
+#define NDN_GEP_TLV_HPP
+
+namespace ndn {
+namespace gep {
+namespace tlv {
+
+enum {
+  EncryptedContent = 130,
+  EncryptionAlgorithm = 131,
+  EncryptedPayload = 132
+};
+
+enum AlgorithmTypeValue {
+  AlgorithmSha256WithRsa = 0,
+  AlgorithmSha256WithEcdsa = 1
+};
+
+} // namespace tlv
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_GEP_TLV_HPP
diff --git a/tests/unit-tests/encrypted-content.t.cpp b/tests/unit-tests/encrypted-content.t.cpp
new file mode 100644
index 0000000..e53b3f1
--- /dev/null
+++ b/tests/unit-tests/encrypted-content.t.cpp
@@ -0,0 +1,216 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "encrypted-content.hpp"
+
+#include "boost-test.hpp"
+#include <algorithm>
+
+namespace ndn {
+namespace gep {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(TestEncryptedContent)
+
+const uint8_t encrypted[] = {
+0x82, 0x24, // EncryptedContent
+  0x1c, 0x16, // KeyLocator
+    0x07, 0x14, // Name
+      0x08, 0x04,
+        0x74, 0x65, 0x73, 0x74, // 'test'
+      0x08, 0x03,
+        0x6b, 0x65, 0x79, // 'key'
+      0x08, 0x07,
+        0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, // 'locator'
+  0x83, 0x01, // EncryptedAlgorithm
+    0x00,
+  0x84, 0x07, // EncryptedPayload
+    0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+};
+
+const uint8_t message[] = {
+  0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+};
+
+BOOST_AUTO_TEST_CASE(Constructor)
+{
+  EncryptedContent content;
+  BOOST_CHECK_EQUAL(content.getAlgorithmType(), -1);
+  BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+  BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
+  BOOST_CHECK_THROW(content.getKeyLocator(), EncryptedContent::Error);
+
+  ConstBufferPtr payload = make_shared<Buffer>(message, sizeof(message));
+  KeyLocator keyLocator("test/key/locator");
+  EncryptedContent sha256RsaContent(tlv::AlgorithmSha256WithRsa, keyLocator, payload);
+  ConstBufferPtr contentPayload = sha256RsaContent.getPayload();
+
+  BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
+                                contentPayload->end(),
+                                payload->begin(),
+                                payload->end());
+  BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
+  BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
+  BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
+
+  Block encryptedBlock(encrypted, sizeof(encrypted));
+  const Block& encoded = sha256RsaContent.wireEncode();
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(encryptedBlock.wire(),
+                                encryptedBlock.wire() + encryptedBlock.size(),
+                                encoded.wire(),
+                                encoded.wire() + encoded.size());
+
+  sha256RsaContent = EncryptedContent(encryptedBlock);
+  contentPayload = sha256RsaContent.getPayload();
+
+  BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
+  BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
+                                contentPayload->end(),
+                                payload->begin(),
+                                payload->end());
+  BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
+  BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
+}
+
+BOOST_AUTO_TEST_CASE(ConstructorError)
+{
+  const uint8_t error1[] = {
+    0x1f, 0x24, // Wrong EncryptedContent (0x82, 0x24)
+      0x1c, 0x16, // KeyLocator
+        0x07, 0x14, // Name
+          0x08, 0x04,
+            0x74, 0x65, 0x73, 0x74,
+          0x08, 0x03,
+            0x6b, 0x65, 0x79,
+          0x08, 0x07,
+            0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
+      0x83, 0x01, // EncryptedAlgorithm
+        0x00,
+      0x84, 0x07, // EncryptedPayload
+        0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+  };
+  Block errorBlock1(error1, sizeof(error1));
+  BOOST_CHECK_THROW(EncryptedContent info(errorBlock1), EncryptedContent::Error);
+
+  const uint8_t error2[] = {
+    0x82, 0x24, // EncryptedContent
+      0x1d, 0x16, // Wrong KeyLocator (0x1c, 0x16)
+        0x07, 0x14, // Name
+          0x08, 0x04,
+            0x74, 0x65, 0x73, 0x74,
+          0x08, 0x03,
+            0x6b, 0x65, 0x79,
+          0x08, 0x07,
+            0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
+      0x83, 0x01, // EncryptedAlgorithm
+        0x00,
+      0x84, 0x07, // EncryptedPayload
+        0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+  };
+  Block errorBlock2(error2, sizeof(error2));
+  BOOST_CHECK_THROW(EncryptedContent info(errorBlock2), EncryptedContent::Error);
+
+  const uint8_t error3[] = {
+    0x82, 0x24, // EncryptedContent
+      0x1c, 0x16, // KeyLocator
+        0x07, 0x14, // Name
+          0x08, 0x04,
+            0x74, 0x65, 0x73, 0x74,
+          0x08, 0x03,
+            0x6b, 0x65, 0x79,
+          0x08, 0x07,
+            0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
+      0x1d, 0x01, // Wrong EncryptedAlgorithm (0x83, 0x01)
+        0x00,
+      0x84, 0x07, // EncryptedPayload
+        0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+  };
+  Block errorBlock3(error3, sizeof(error3));
+  BOOST_CHECK_THROW(EncryptedContent info(errorBlock3), EncryptedContent::Error);
+
+  const uint8_t error4[] = {
+    0x82, 0x24, // EncryptedContent
+      0x1c, 0x16, // KeyLocator
+        0x07, 0x14, // Name
+          0x08, 0x04,
+            0x74, 0x65, 0x73, 0x74, // 'test'
+          0x08, 0x03,
+            0x6b, 0x65, 0x79, // 'key'
+          0x08, 0x07,
+            0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, // 'locator'
+      0x83, 0x01, // EncryptedAlgorithm
+        0x00,
+      0x21, 0x07, // EncryptedPayload (0x84, 0x07)
+        0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+  };
+  Block errorBlock4(error4, sizeof(error4));
+  BOOST_CHECK_THROW(EncryptedContent info(errorBlock4), EncryptedContent::Error);
+
+  const uint8_t error5[] = {
+    0x82, 0x00 // Empty EncryptedContent
+  };
+  Block errorBlock5(error5, sizeof(error5));
+  BOOST_CHECK_THROW(EncryptedContent info(errorBlock5), EncryptedContent::Error);
+}
+
+BOOST_AUTO_TEST_CASE(SetterGetter)
+{
+  EncryptedContent content;
+  BOOST_CHECK_EQUAL(content.getAlgorithmType(), -1);
+  BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+  BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
+  BOOST_CHECK_THROW(content.getKeyLocator(), EncryptedContent::Error);
+
+  content.setAlgorithmType(tlv::AlgorithmSha256WithRsa);
+  BOOST_CHECK_EQUAL(content.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
+  BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+  BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
+
+  KeyLocator keyLocator("/test/key/locator");
+  content.setKeyLocator(keyLocator);
+  BOOST_CHECK_EQUAL(content.hasKeyLocator(), true);
+  BOOST_CHECK_NO_THROW(content.getKeyLocator());
+  BOOST_CHECK_EQUAL(content.getKeyLocator().getName(), Name("/test/key/locator"));
+  BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+
+  ConstBufferPtr payload = make_shared<Buffer>(message, sizeof(message));
+  content.setPayload(payload);
+
+  ConstBufferPtr contentPayload = content.getPayload();
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
+                                contentPayload->end(),
+                                payload->begin(),
+                                payload->end());
+
+  const Block& encoded = content.wireEncode();
+  Block contentBlock(encrypted, sizeof(encrypted));
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(contentBlock.wire(),
+                                contentBlock.wire() + contentBlock.size(),
+                                encoded.wire(),
+                                encoded.wire() + encoded.size());
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace gep
+} // namespace ndn
