Adding optional initial vector to EncryptedContent

Refs: #3013

Change-Id: I1c6fea3552796d13525d33e3a9d385156e2d463e
diff --git a/src/encrypted-content.cpp b/src/encrypted-content.cpp
index 0a7c9e1..29f8ceb 100644
--- a/src/encrypted-content.cpp
+++ b/src/encrypted-content.cpp
@@ -19,11 +19,13 @@
 {
 }
 
-EncryptedContent::EncryptedContent(tlv::AlgorithmTypeValue type, const KeyLocator& keyLocator, const ConstBufferPtr& payload)
+EncryptedContent::EncryptedContent(tlv::AlgorithmTypeValue type, const KeyLocator& keyLocator,
+                                   ConstBufferPtr payload, ConstBufferPtr iv)
   : m_type(type)
   , m_hasKeyLocator(true)
   , m_keyLocator(keyLocator)
   , m_payload(payload)
+  , m_iv(iv)
 {
 }
 
@@ -57,13 +59,26 @@
 }
 
 void
-EncryptedContent::setPayload(const ConstBufferPtr& payload)
+EncryptedContent::setInitialVector(ConstBufferPtr iv)
+{
+  m_wire.reset();
+  m_iv = iv;
+}
+
+ConstBufferPtr
+EncryptedContent::getInitialVector() const
+{
+  return m_iv;
+}
+
+void
+EncryptedContent::setPayload(ConstBufferPtr payload)
 {
   m_wire.reset();
   m_payload = payload;
 }
 
-const ConstBufferPtr
+ConstBufferPtr
 EncryptedContent::getPayload() const
 {
   return m_payload;
@@ -75,7 +90,13 @@
 {
   size_t totalLength = 0;
 
-  totalLength += block.appendByteArrayBlock(tlv::EncryptedPayload, m_payload->buf(), m_payload->size());
+  if (m_payload != nullptr)
+    totalLength += block.prependByteArrayBlock(tlv::EncryptedPayload, m_payload->buf(), m_payload->size());
+  else
+    throw Error("EncryptedContent does not have a payload");
+
+  if (m_iv != nullptr)
+    totalLength += block.prependByteArrayBlock(tlv::InitialVector, m_iv->buf(), m_iv->size());
 
   if (m_type != -1)
     totalLength += prependNonNegativeIntegerBlock(block, tlv::EncryptionAlgorithm, m_type);
@@ -85,7 +106,7 @@
   if (m_hasKeyLocator)
     totalLength += m_keyLocator.wireEncode(block);
   else
-    throw Error("EncryptedContent does not have key locator");
+    throw Error("EncryptedContent does not have a key locator");
 
   totalLength += block.prependVarNumber(totalLength);
   totalLength += block.prependVarNumber(tlv::EncryptedContent);
@@ -140,8 +161,15 @@
   else
     throw Error("EncryptedContent does not have encryption algorithm");
 
+  if (it != m_wire.elements_end() && it->type() == tlv::InitialVector) {
+    m_iv = make_shared<Buffer>(it->value_begin(), it->value_end());
+    it++;
+  }
+  else
+    m_iv = nullptr;
+
   if (it != m_wire.elements_end() && it->type() == tlv::EncryptedPayload) {
-    m_payload = make_shared<Buffer>(it->value_begin(),it->value_end());
+    m_payload = make_shared<Buffer>(it->value_begin(), it->value_end());
     it++;
   }
   else
diff --git a/src/encrypted-content.hpp b/src/encrypted-content.hpp
index 2d0203e..c31d705 100644
--- a/src/encrypted-content.hpp
+++ b/src/encrypted-content.hpp
@@ -26,7 +26,8 @@
 public:
   EncryptedContent();
 
-  EncryptedContent(tlv::AlgorithmTypeValue type, const KeyLocator& keyLocator, const ConstBufferPtr& payload);
+  EncryptedContent(tlv::AlgorithmTypeValue type, const KeyLocator& keyLocator,
+                   ConstBufferPtr payload, ConstBufferPtr iv = nullptr);
 
   explicit
   EncryptedContent(const Block& block);
@@ -53,9 +54,15 @@
   getKeyLocator() const;
 
   void
-  setPayload(const ConstBufferPtr& payload);
+  setInitialVector(ConstBufferPtr iv);
 
-  const ConstBufferPtr
+  ConstBufferPtr
+  getInitialVector() const;
+
+  void
+  setPayload(ConstBufferPtr payload);
+
+  ConstBufferPtr
   getPayload() const;
 
   template<encoding::Tag TAG>
@@ -82,6 +89,7 @@
   bool m_hasKeyLocator;
   KeyLocator m_keyLocator;
   ConstBufferPtr m_payload;
+  ConstBufferPtr m_iv;
 
   mutable Block m_wire;
 };
diff --git a/src/tlv.hpp b/src/tlv.hpp
index 92f2f4e..a94af47 100644
--- a/src/tlv.hpp
+++ b/src/tlv.hpp
@@ -29,7 +29,8 @@
 enum {
   EncryptedContent = 130,
   EncryptionAlgorithm = 131,
-  EncryptedPayload = 132
+  EncryptedPayload = 132,
+  InitialVector = 133
 };
 
 enum AlgorithmTypeValue {