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 {
diff --git a/tests/unit-tests/encrypted-content.t.cpp b/tests/unit-tests/encrypted-content.t.cpp
index e53b3f1..878d0e9 100644
--- a/tests/unit-tests/encrypted-content.t.cpp
+++ b/tests/unit-tests/encrypted-content.t.cpp
@@ -29,6 +29,24 @@
BOOST_AUTO_TEST_SUITE(TestEncryptedContent)
const uint8_t encrypted[] = {
+0x82, 0x30, // 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,
+ 0x85, 0x0a, // InitialVector
+ 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
+ 0x84, 0x07, // EncryptedPayload
+ 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
+};
+
+const uint8_t encrypted_noiv[] = {
0x82, 0x24, // EncryptedContent
0x1c, 0x16, // KeyLocator
0x07, 0x14, // Name
@@ -48,24 +66,36 @@
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
};
+const uint8_t iv[] = {
+ 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73
+};
+
BOOST_AUTO_TEST_CASE(Constructor)
{
EncryptedContent content;
BOOST_CHECK_EQUAL(content.getAlgorithmType(), -1);
BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+ BOOST_CHECK_EQUAL(content.getInitialVector() == nullptr, true);
BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
BOOST_CHECK_THROW(content.getKeyLocator(), EncryptedContent::Error);
ConstBufferPtr payload = make_shared<Buffer>(message, sizeof(message));
+ ConstBufferPtr initialVector = make_shared<Buffer>(iv, sizeof(iv));
+
KeyLocator keyLocator("test/key/locator");
- EncryptedContent sha256RsaContent(tlv::AlgorithmSha256WithRsa, keyLocator, payload);
+ EncryptedContent sha256RsaContent(tlv::AlgorithmSha256WithRsa, keyLocator, payload, initialVector);
ConstBufferPtr contentPayload = sha256RsaContent.getPayload();
+ ConstBufferPtr contentInitialVector = sha256RsaContent.getInitialVector();
BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
contentPayload->end(),
payload->begin(),
payload->end());
+ BOOST_CHECK_EQUAL_COLLECTIONS(contentInitialVector->begin(),
+ contentInitialVector->end(),
+ initialVector->begin(),
+ initialVector->end());
BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
@@ -80,6 +110,7 @@
sha256RsaContent = EncryptedContent(encryptedBlock);
contentPayload = sha256RsaContent.getPayload();
+ contentInitialVector = sha256RsaContent.getInitialVector();
BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
@@ -87,14 +118,52 @@
contentPayload->end(),
payload->begin(),
payload->end());
+ BOOST_CHECK_EQUAL_COLLECTIONS(contentInitialVector->begin(),
+ contentInitialVector->end(),
+ initialVector->begin(),
+ initialVector->end());
BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
+
+ sha256RsaContent = EncryptedContent(tlv::AlgorithmSha256WithRsa, keyLocator, payload);
+
+ BOOST_CHECK_EQUAL(sha256RsaContent.getAlgorithmType(), tlv::AlgorithmSha256WithRsa);
+ BOOST_CHECK_EQUAL_COLLECTIONS(contentPayload->begin(),
+ contentPayload->end(),
+ payload->begin(),
+ payload->end());
+ BOOST_CHECK_EQUAL(sha256RsaContent.getInitialVector() == nullptr, true);
+ BOOST_CHECK_EQUAL(sha256RsaContent.hasKeyLocator(), true);
+ BOOST_CHECK_NO_THROW(sha256RsaContent.getKeyLocator());
+ BOOST_CHECK_EQUAL(sha256RsaContent.getKeyLocator().getName(), Name("test/key/locator"));
+
+ encryptedBlock = Block(encrypted_noiv, sizeof(encrypted_noiv));
+ const Block& encodedNoIV = sha256RsaContent.wireEncode();
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(encryptedBlock.wire(),
+ encryptedBlock.wire() + encryptedBlock.size(),
+ encodedNoIV.wire(),
+ encodedNoIV.wire() + encodedNoIV.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_EQUAL(sha256RsaContent.getInitialVector() == nullptr, true);
+ 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)
+ 0x1f, 0x30, // Wrong EncryptedContent (0x82, 0x24)
0x1c, 0x16, // KeyLocator
0x07, 0x14, // Name
0x08, 0x04,
@@ -105,6 +174,8 @@
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
0x83, 0x01, // EncryptedAlgorithm
0x00,
+ 0x85, 0x0a, // InitialVector
+ 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
0x84, 0x07, // EncryptedPayload
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
};
@@ -112,7 +183,7 @@
BOOST_CHECK_THROW(EncryptedContent info(errorBlock1), EncryptedContent::Error);
const uint8_t error2[] = {
- 0x82, 0x24, // EncryptedContent
+ 0x82, 0x30, // EncryptedContent
0x1d, 0x16, // Wrong KeyLocator (0x1c, 0x16)
0x07, 0x14, // Name
0x08, 0x04,
@@ -123,6 +194,8 @@
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
0x83, 0x01, // EncryptedAlgorithm
0x00,
+ 0x85, 0x0a, // InitialVector
+ 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
0x84, 0x07, // EncryptedPayload
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
};
@@ -130,7 +203,7 @@
BOOST_CHECK_THROW(EncryptedContent info(errorBlock2), EncryptedContent::Error);
const uint8_t error3[] = {
- 0x82, 0x24, // EncryptedContent
+ 0x82, 0x30, // EncryptedContent
0x1c, 0x16, // KeyLocator
0x07, 0x14, // Name
0x08, 0x04,
@@ -141,6 +214,8 @@
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
0x1d, 0x01, // Wrong EncryptedAlgorithm (0x83, 0x01)
0x00,
+ 0x85, 0x0a, // InitialVector
+ 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
0x84, 0x07, // EncryptedPayload
0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
};
@@ -148,7 +223,7 @@
BOOST_CHECK_THROW(EncryptedContent info(errorBlock3), EncryptedContent::Error);
const uint8_t error4[] = {
- 0x82, 0x24, // EncryptedContent
+ 0x82, 0x30, // EncryptedContent
0x1c, 0x16, // KeyLocator
0x07, 0x14, // Name
0x08, 0x04,
@@ -159,17 +234,39 @@
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, // 'locator'
0x83, 0x01, // EncryptedAlgorithm
0x00,
- 0x21, 0x07, // EncryptedPayload (0x84, 0x07)
+ 0x1f, 0x0a, // InitialVector (0x84, 0x0a)
+ 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
+ 0x84, 0x07, // EncryptedPayload
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
+ 0x82, 0x30, // 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,
+ 0x85, 0x0a, // InitialVector
+ 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x62, 0x69, 0x74, 0x73,
+ 0x21, 0x07, // EncryptedPayload (0x85, 0x07)
+ 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74
};
Block errorBlock5(error5, sizeof(error5));
BOOST_CHECK_THROW(EncryptedContent info(errorBlock5), EncryptedContent::Error);
+
+ const uint8_t error6[] = {
+ 0x82, 0x00 // Empty EncryptedContent
+ };
+ Block errorBlock6(error6, sizeof(error6));
+ BOOST_CHECK_THROW(EncryptedContent info(errorBlock6), EncryptedContent::Error);
}
BOOST_AUTO_TEST_CASE(SetterGetter)
@@ -177,12 +274,14 @@
EncryptedContent content;
BOOST_CHECK_EQUAL(content.getAlgorithmType(), -1);
BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+ BOOST_CHECK_EQUAL(content.getInitialVector() == 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.getInitialVector() == nullptr, true);
BOOST_CHECK_EQUAL(content.hasKeyLocator(), false);
KeyLocator keyLocator("/test/key/locator");
@@ -191,6 +290,7 @@
BOOST_CHECK_NO_THROW(content.getKeyLocator());
BOOST_CHECK_EQUAL(content.getKeyLocator().getName(), Name("/test/key/locator"));
BOOST_CHECK_EQUAL(content.getPayload() == nullptr, true);
+ BOOST_CHECK_EQUAL(content.getInitialVector() == nullptr, true);
ConstBufferPtr payload = make_shared<Buffer>(message, sizeof(message));
content.setPayload(payload);
@@ -201,6 +301,15 @@
payload->begin(),
payload->end());
+ ConstBufferPtr initialVector = make_shared<Buffer>(iv, sizeof(iv));
+ content.setInitialVector(initialVector);
+
+ ConstBufferPtr contentInitialVector = content.getInitialVector();
+ BOOST_CHECK_EQUAL_COLLECTIONS(contentInitialVector->begin(),
+ contentInitialVector->end(),
+ initialVector->begin(),
+ initialVector->end());
+
const Block& encoded = content.wireEncode();
Block contentBlock(encrypted, sizeof(encrypted));