update crypto helper
Change-Id: I59718964ce305888a8fc3947cde68c937a3ba64a
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index d64d904..c662617 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -349,8 +349,10 @@
// decrypt the parameters
Buffer paramTLVPayload;
try {
- paramTLVPayload = decodeBlockWithAesGcm128(request.getApplicationParameters(), requestState.m_encryptionKey.value(),
- (uint8_t*)"test", strlen("test"));
+ paramTLVPayload = decodeBlockWithAesGcm128(request.getApplicationParameters(),
+ requestState.m_encryptionKey.value(),
+ (const uint8_t*)requestState.m_requestId.c_str(),
+ requestState.m_requestId.size());
}
catch (const std::exception& e) {
NDN_LOG_ERROR("Interest paramaters decryption failed: " << e.what());
@@ -419,8 +421,11 @@
Data result;
result.setName(request.getName());
result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
- auto contentBlock = encodeBlockWithAesGcm128(ndn::tlv::Content, requestState.m_encryptionKey.value(), payload.value(),
- payload.value_size(), (uint8_t*)"test", strlen("test"));
+ auto contentBlock = encodeBlockWithAesGcm128(ndn::tlv::Content, requestState.m_encryptionKey.value(),
+ payload.value(), payload.value_size(),
+ (const uint8_t*)requestState.m_requestId.c_str(),
+ requestState.m_requestId.size(),
+ requestState.m_aesBlockCounter);
result.setContent(contentBlock);
m_keyChain.sign(result, signingByIdentity(m_config.m_caItem.m_caPrefix));
m_face.put(result);
diff --git a/src/detail/ca-sqlite.cpp b/src/detail/ca-sqlite.cpp
index b0d6af5..468fd2c 100644
--- a/src/detail/ca-sqlite.cpp
+++ b/src/detail/ca-sqlite.cpp
@@ -66,7 +66,8 @@
remaining_tries INTEGER,
remaining_time INTEGER,
challenge_secrets TEXT,
- encryption_key BLOB NOT NULL
+ encryption_key BLOB NOT NULL,
+ aes_block_counter INTEGER
);
CREATE UNIQUE INDEX IF NOT EXISTS
CaStateIdIndex ON CaStates(request_id);
@@ -128,7 +129,8 @@
R"_SQLTEXT_(SELECT id, ca_name, status,
challenge_status, cert_request,
challenge_type, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time, request_type, encryption_key
+ challenge_tp, remaining_tries, remaining_time,
+ request_type, encryption_key, aes_block_counter
FROM CaStates where request_id = ?)_SQLTEXT_");
statement.bind(1, requestId, SQLITE_TRANSIENT);
@@ -144,11 +146,12 @@
auto remainingTime = statement.getInt(9);
auto requestType = static_cast<RequestType>(statement.getInt(10));
auto encryptionKey = statement.getBlock(11);
+ auto aesCounter = statement.getInt(12);
if (challengeType != "") {
return CaState(caName, requestId, requestType, status, cert,
challengeType, challengeStatus, time::fromIsoString(challengeTp),
remainingTries, time::seconds(remainingTime),
- convertString2Json(challengeSecrets), encryptionKey);
+ convertString2Json(challengeSecrets), encryptionKey, aesCounter);
}
else {
return CaState(caName, requestId, requestType, status, cert, encryptionKey);
@@ -166,14 +169,15 @@
m_database,
R"_SQLTEXT_(INSERT OR ABORT INTO CaStates (request_id, ca_name, status, request_type,
cert_request, challenge_type, challenge_status, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time, encryption_key)
- values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?))_SQLTEXT_");
+ challenge_tp, remaining_tries, remaining_time, encryption_key, aes_block_counter)
+ values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?))_SQLTEXT_");
statement.bind(1, request.m_requestId, SQLITE_TRANSIENT);
statement.bind(2, request.m_caPrefix.wireEncode(), SQLITE_TRANSIENT);
statement.bind(3, static_cast<int>(request.m_status));
statement.bind(4, static_cast<int>(request.m_requestType));
statement.bind(5, request.m_cert.wireEncode(), SQLITE_TRANSIENT);
statement.bind(12, request.m_encryptionKey, SQLITE_TRANSIENT);
+ statement.bind(13, request.m_aesBlockCounter);
if (request.m_challengeState) {
statement.bind(6, request.m_challengeType, SQLITE_TRANSIENT);
statement.bind(7, request.m_challengeState->m_challengeStatus, SQLITE_TRANSIENT);
@@ -194,7 +198,7 @@
Sqlite3Statement statement(m_database,
R"_SQLTEXT_(UPDATE CaStates
SET status = ?, challenge_type = ?, challenge_status = ?, challenge_secrets = ?,
- challenge_tp = ?, remaining_tries = ?, remaining_time = ?
+ challenge_tp = ?, remaining_tries = ?, remaining_time = ?, aes_block_counter = ?
WHERE request_id = ?)_SQLTEXT_");
statement.bind(1, static_cast<int>(request.m_status));
statement.bind(2, request.m_challengeType, SQLITE_TRANSIENT);
@@ -212,7 +216,8 @@
statement.bind(6, 0);
statement.bind(7, 0);
}
- statement.bind(8, request.m_requestId, SQLITE_TRANSIENT);
+ statement.bind(8, request.m_aesBlockCounter);
+ statement.bind(9, request.m_requestId, SQLITE_TRANSIENT);
if (statement.step() != SQLITE_DONE) {
addRequest(request);
@@ -225,7 +230,8 @@
std::list<CaState> result;
Sqlite3Statement statement(m_database, R"_SQLTEXT_(SELECT id, request_id, ca_name, status,
challenge_status, cert_request, challenge_type, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time, request_type, encryption_key
+ challenge_tp, remaining_tries, remaining_time, request_type,
+ encryption_key, aes_block_counter
FROM CaStates)_SQLTEXT_");
while (statement.step() == SQLITE_ROW) {
auto requestId = statement.getString(1);
@@ -240,14 +246,15 @@
auto remainingTime = statement.getInt(10);
auto requestType = static_cast<RequestType>(statement.getInt(11));
auto encryptionKey = statement.getBlock(12);
+ auto aesBlockCounter = statement.getInt(13);
if (challengeType != "") {
result.push_back(CaState(caName, requestId, requestType, status, cert,
challengeType, challengeStatus, time::fromIsoString(challengeTp),
remainingTries, time::seconds(remainingTime),
- convertString2Json(challengeSecrets), encryptionKey));
+ convertString2Json(challengeSecrets), encryptionKey, aesBlockCounter));
}
else {
- result.push_back(CaState(caName, requestId, requestType, status, cert, encryptionKey));
+ result.push_back(CaState(caName, requestId, requestType, status, cert, encryptionKey, aesBlockCounter));
}
}
return result;
@@ -260,7 +267,8 @@
Sqlite3Statement statement(m_database,
R"_SQLTEXT_(SELECT id, request_id, ca_name, status,
challenge_status, cert_request, challenge_type, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time, request_type, encryption_key
+ challenge_tp, remaining_tries, remaining_time, request_type,
+ encryption_key, aes_block_counter
FROM CaStates WHERE ca_name = ?)_SQLTEXT_");
statement.bind(1, caName.wireEncode(), SQLITE_TRANSIENT);
@@ -277,14 +285,15 @@
auto remainingTime = statement.getInt(10);
auto requestType = static_cast<RequestType>(statement.getInt(11));
auto encryptionKey = statement.getBlock(12);
+ auto aesBlockCounter = statement.getInt(13);
if (challengeType != "") {
result.push_back(CaState(caName, requestId, requestType, status, cert,
challengeType, challengeStatus, time::fromIsoString(challengeTp),
remainingTries, time::seconds(remainingTime),
- convertString2Json(challengeSecrets), encryptionKey));
+ convertString2Json(challengeSecrets), encryptionKey, aesBlockCounter));
}
else {
- result.push_back(CaState(caName, requestId, requestType, status, cert, encryptionKey));
+ result.push_back(CaState(caName, requestId, requestType, status, cert, encryptionKey, aesBlockCounter));
}
}
return result;
diff --git a/src/detail/ca-state.cpp b/src/detail/ca-state.cpp
index 185fbdd..334429a 100644
--- a/src/detail/ca-state.cpp
+++ b/src/detail/ca-state.cpp
@@ -65,13 +65,14 @@
}
CaState::CaState(const Name& caName, const std::string& requestId, RequestType requestType, Status status,
- const security::Certificate& cert, Block encryptionKey)
+ const security::Certificate& cert, Block encryptionKey, uint32_t aesBlockCounter)
: m_caPrefix(caName)
, m_requestId(requestId)
, m_requestType(requestType)
, m_status(status)
, m_cert(cert)
, m_encryptionKey(std::move(encryptionKey))
+ , m_aesBlockCounter(aesBlockCounter)
{
}
@@ -79,13 +80,14 @@
const security::Certificate& cert, const std::string& challengeType,
const std::string& challengeStatus, const time::system_clock::TimePoint& challengeTp,
size_t remainingTries, time::seconds remainingTime, JsonSection&& challengeSecrets,
- Block encryptionKey)
+ Block encryptionKey, uint32_t aesBlockCounter)
: m_caPrefix(caName)
, m_requestId(requestId)
, m_requestType(requestType)
, m_status(status)
, m_cert(cert)
, m_encryptionKey(std::move(encryptionKey))
+ , m_aesBlockCounter(aesBlockCounter)
, m_challengeType(challengeType)
, m_challengeState(ChallengeState(challengeStatus, challengeTp, remainingTries, remainingTime, std::move(challengeSecrets)))
{
diff --git a/src/detail/ca-state.hpp b/src/detail/ca-state.hpp
index 2204f1c..9f30b6d 100644
--- a/src/detail/ca-state.hpp
+++ b/src/detail/ca-state.hpp
@@ -66,12 +66,12 @@
public:
CaState();
CaState(const Name& caName, const std::string& requestId, RequestType requestType, Status status,
- const security::Certificate& cert, Block m_encryptionKey);
+ const security::Certificate& cert, Block m_encryptionKey, uint32_t aesBlockCounter = 0);
CaState(const Name& caName, const std::string& requestId, RequestType requestType, Status status,
const security::Certificate& cert, const std::string& challengeType,
const std::string& challengeStatus, const time::system_clock::TimePoint& challengeTp,
size_t remainingTries, time::seconds remainingTime, JsonSection&& challengeSecrets,
- Block m_encryptionKey);
+ Block m_encryptionKey, uint32_t aesBlockCounter);
public:
Name m_caPrefix;
@@ -80,6 +80,7 @@
Status m_status;
security::Certificate m_cert;
Block m_encryptionKey;
+ uint32_t m_aesBlockCounter = 0;
std::string m_challengeType;
boost::optional<ChallengeState> m_challengeState;
diff --git a/src/detail/crypto-helper.cpp b/src/detail/crypto-helper.cpp
index 1cd974a..86970f9 100644
--- a/src/detail/crypto-helper.cpp
+++ b/src/detail/crypto-helper.cpp
@@ -19,6 +19,7 @@
*/
#include "crypto-helper.hpp"
+#include <cmath>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/pem.h>
@@ -31,6 +32,7 @@
#include <ndn-cxx/security/transform/buffer-source.hpp>
#include <ndn-cxx/security/transform/stream-sink.hpp>
#include <ndn-cxx/util/random.hpp>
+#include <boost/endian/conversion.hpp>
namespace ndn {
namespace ndncert {
@@ -206,24 +208,31 @@
{
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr);
if (EVP_PKEY_derive_init(pctx) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
NDN_THROW(std::runtime_error("HKDF: Cannot init ctx when calling EVP_PKEY_derive_init()."));
}
if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
NDN_THROW(std::runtime_error("HKDF: Cannot set md when calling EVP_PKEY_CTX_set_hkdf_md()."));
}
if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, salt_len) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
NDN_THROW(std::runtime_error("HKDF: Cannot set salt when calling EVP_PKEY_CTX_set1_hkdf_salt()."));
}
if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, secret_len) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
NDN_THROW(std::runtime_error("HKDF: Cannot set secret when calling EVP_PKEY_CTX_set1_hkdf_key()."));
}
if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info, info_len) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
NDN_THROW(std::runtime_error("HKDF: Cannot set info when calling EVP_PKEY_CTX_add1_hkdf_info()."));
}
size_t outLen = output_len;
if (EVP_PKEY_derive(pctx, output, &outLen) <= 0) {
+ EVP_PKEY_CTX_free(pctx);
NDN_THROW(std::runtime_error("HKDF: Cannot derive result when calling EVP_PKEY_derive()."));
}
+ EVP_PKEY_CTX_free(pctx);
return (int)outLen;
}
@@ -350,22 +359,32 @@
Block
encodeBlockWithAesGcm128(uint32_t tlv_type, const uint8_t* key, const uint8_t* payload, size_t payloadSize,
- const uint8_t* associatedData, size_t associatedDataSize)
+ const uint8_t* associatedData, size_t associatedDataSize, uint32_t& counter)
{
- Buffer iv;
- iv.resize(12);
+ Buffer iv(12);
random::generateSecureBytes(iv.data(), iv.size());
+ if (tlv_type == ndn::tlv::ApplicationParameters) {
+ // requester
+ iv[0] &= ~(1UL << 7);
+ }
+ else {
+ // CA
+ iv[0] |= 1UL << 7;
+ }
+ uint32_t temp = counter;
+ boost::endian::native_to_big_inplace(temp);
+ std::memcpy(&iv[8], reinterpret_cast<const uint8_t*>(&temp), 4);
+ counter += std::ceil(payloadSize / 8);
- uint8_t* encryptedPayload = new uint8_t[payloadSize];
+ Buffer encryptedPayload(payloadSize);
uint8_t tag[16];
size_t encryptedPayloadLen = aes_gcm_128_encrypt(payload, payloadSize, associatedData, associatedDataSize,
- key, iv.data(), encryptedPayload, tag);
+ key, iv.data(), encryptedPayload.data(), tag);
auto content = makeEmptyBlock(tlv_type);
content.push_back(makeBinaryBlock(tlv::InitializationVector, iv.data(), iv.size()));
content.push_back(makeBinaryBlock(tlv::AuthenticationTag, tag, 16));
- content.push_back(makeBinaryBlock(tlv::EncryptedPayload, encryptedPayload, encryptedPayloadLen));
+ content.push_back(makeBinaryBlock(tlv::EncryptedPayload, encryptedPayload.data(), encryptedPayloadLen));
content.encode();
- delete[] encryptedPayload;
return content;
}
diff --git a/src/detail/crypto-helper.hpp b/src/detail/crypto-helper.hpp
index 2e8f7af..8463eb6 100644
--- a/src/detail/crypto-helper.hpp
+++ b/src/detail/crypto-helper.hpp
@@ -134,11 +134,12 @@
* @param payloadSize The size of the plaintext payload.
* @param associatedData The associated data used for authentication.
* @param associatedDataSize The size of associated data.
+ * @param counter The counter of blocks that have been encrypted by the requester/CA.
* @return Block The TLV block with @param tlv_type TLV TYPE.
*/
Block
encodeBlockWithAesGcm128(uint32_t tlv_type, const uint8_t* key, const uint8_t* payload, size_t payloadSize,
- const uint8_t* associatedData, size_t associatedDataSize);
+ const uint8_t* associatedData, size_t associatedDataSize, uint32_t& counter);
/**
* @brief Decode the payload from TLV block with Authenticated GCM 128 Encryption.
diff --git a/src/requester-state.hpp b/src/requester-state.hpp
index 09c46ac..73f6737 100644
--- a/src/requester-state.hpp
+++ b/src/requester-state.hpp
@@ -33,63 +33,67 @@
RequesterState(security::KeyChain& keyChain, const CaProfile& caItem, RequestType requestType);
/**
- * The CA profile for this request.
+ * @brief The CA profile for this request.
*/
CaProfile m_caItem;
/**
- * The local keychain to generate and install identities, keys and certificates
+ * @brief The local keychain to generate and install identities, keys and certificates
*/
security::KeyChain& m_keyChain;
/**
- * The type of request. Either NEW, RENEW, or REVOKE.
+ * @brief The type of request. Either NEW, RENEW, or REVOKE.
*/
RequestType m_type;
/**
- * The identity name for the requesting certificate.
+ * @brief The identity name for the requesting certificate.
*/
Name m_identityName;
/**
- * The keypair for the request.
+ * @brief The keypair for the request.
*/
security::Key m_keyPair;
/**
- * The CA-generated request ID for the request.
+ * @brief The CA-generated request ID for the request.
*/
std::string m_requestId;
/**
- * The current status of the request.
+ * @brief The current status of the request.
*/
Status m_status = Status::NOT_STARTED;
/**
- * The type of challenge chosen.
+ * @brief The type of challenge chosen.
*/
std::string m_challengeType;
/**
- * The status of the current challenge.
+ * @brief The status of the current challenge.
*/
std::string m_challengeStatus;
/**
- * The remaining number of tries left for the challenge
+ * @brief The remaining number of tries left for the challenge
*/
int m_remainingTries = 0;
/**
- * The time this challenge will remain fresh
+ * @brief The time this challenge will remain fresh
*/
time::system_clock::TimePoint m_freshBefore;
/**
- * the name of the certificate being issued.
+ * @brief the name of the certificate being issued.
*/
Name m_issuedCertName;
/**
- * ecdh state.
+ * @brief ecdh state.
*/
ECDHState m_ecdh;
/**
- * AES key derived from the ecdh shared secret.
+ * @brief AES key derived from the ecdh shared secret.
*/
uint8_t m_aesKey[16] = {0};
/**
- * State about how identity/key is generated.
+ * @brief The counter of AES blocks that have been encrypted.
+ */
+ uint32_t m_aesBlockCounter = 0;
+ /**
+ * @brief State about how identity/key is generated.
*/
bool m_isNewlyCreatedIdentity = false;
bool m_isNewlyCreatedKey = false;
diff --git a/src/requester.cpp b/src/requester.cpp
index 4368700..1e503d5 100644
--- a/src/requester.cpp
+++ b/src/requester.cpp
@@ -224,7 +224,7 @@
}
shared_ptr<Interest>
-Requester::genChallengeInterest(const RequesterState& state,
+Requester::genChallengeInterest(RequesterState& state,
std::vector<std::tuple<std::string, std::string>>&& parameters)
{
if (state.m_challengeType == "") {
@@ -245,7 +245,9 @@
// encrypt the Interest parameters
auto paramBlock = encodeBlockWithAesGcm128(ndn::tlv::ApplicationParameters, state.m_aesKey,
challengeParams.value(), challengeParams.value_size(),
- (const uint8_t*)"test", strlen("test"));
+ (const uint8_t*)state.m_requestId.c_str(),
+ state.m_requestId.size(),
+ state.m_aesBlockCounter);
interest->setApplicationParameters(paramBlock);
state.m_keyChain.sign(*interest, signingByKey(state.m_keyPair.getName()));
return interest;
@@ -259,7 +261,9 @@
NDN_THROW(std::runtime_error("Cannot verify replied Data packet signature."));
}
processIfError(reply);
- auto result = decodeBlockWithAesGcm128(reply.getContent(), state.m_aesKey, (const uint8_t*)"test", strlen("test"));
+ auto result = decodeBlockWithAesGcm128(reply.getContent(), state.m_aesKey,
+ (const uint8_t*)state.m_requestId.c_str(),
+ state.m_requestId.size());
Block contentTLV = makeBinaryBlock(tlv::EncryptedPayload, result.data(), result.size());
ChallengeEncoder::decodeDataContent(contentTLV, state);
}
diff --git a/src/requester.hpp b/src/requester.hpp
index 65cf831..b3c7901 100644
--- a/src/requester.hpp
+++ b/src/requester.hpp
@@ -162,7 +162,7 @@
* @throw std::runtime_error if the challenge is not selected or is not supported.
*/
static shared_ptr<Interest>
- genChallengeInterest(const RequesterState& state,
+ genChallengeInterest(RequesterState& state,
std::vector<std::tuple<std::string, std::string>>&& parameters);
/**
diff --git a/tests/unit-tests/ca-memory.t.cpp b/tests/unit-tests/ca-memory.t.cpp
index b2de610..0dcbd03 100644
--- a/tests/unit-tests/ca-memory.t.cpp
+++ b/tests/unit-tests/ca-memory.t.cpp
@@ -52,7 +52,8 @@
// update operation
CaState request2(Name("/ndn/site1"), "123", RequestType::NEW, Status::CHALLENGE, cert1,
- "email", "test", time::system_clock::now(), 3, time::seconds(3600), std::move(json), makeStringBlock(ndn::tlv::ContentType_Key, "PretendItIsAKey"));
+ "email", "test", time::system_clock::now(), 3, time::seconds(3600),
+ std::move(json), makeStringBlock(ndn::tlv::ContentType_Key, "PretendItIsAKey"), 0);
storage.updateRequest(request2);
result = storage.getRequest("123");
BOOST_CHECK_EQUAL(request2.m_cert, result.m_cert);
diff --git a/tests/unit-tests/ca-sqlite.t.cpp b/tests/unit-tests/ca-sqlite.t.cpp
index 3f98bdb..9bdc30e 100644
--- a/tests/unit-tests/ca-sqlite.t.cpp
+++ b/tests/unit-tests/ca-sqlite.t.cpp
@@ -50,7 +50,8 @@
JsonSection json;
json.put("test", "4567");
CaState request2(Name("/ndn/site1"), "123", RequestType::NEW, Status::CHALLENGE, cert1,
- "email", "test", time::system_clock::now(), 3, time::seconds(3600), std::move(json), makeEmptyBlock(ndn::tlv::ContentType_Key));
+ "email", "test", time::system_clock::now(), 3, time::seconds(3600),
+ std::move(json), makeEmptyBlock(ndn::tlv::ContentType_Key), 0);
storage.updateRequest(request2);
result = storage.getRequest("123");
BOOST_CHECK_EQUAL(request2.m_cert, result.m_cert);
diff --git a/tests/unit-tests/challenge-email.t.cpp b/tests/unit-tests/challenge-email.t.cpp
index 4bac092..b73d22e 100644
--- a/tests/unit-tests/challenge-email.t.cpp
+++ b/tests/unit-tests/challenge-email.t.cpp
@@ -117,7 +117,7 @@
json.put(ChallengeEmail::PARAMETER_KEY_CODE, "4567");
CaState request(Name("/ndn/site1"), "123", RequestType::NEW, Status::CHALLENGE, cert,
"email", ChallengeEmail::NEED_CODE, time::system_clock::now(),
- 3, time::seconds(3600), std::move(json), makeEmptyBlock(ndn::tlv::ContentType_Key));
+ 3, time::seconds(3600), std::move(json), makeEmptyBlock(ndn::tlv::ContentType_Key), 0);
Block paramTLV = makeEmptyBlock(tlv::EncryptedPayload);
paramTLV.push_back(makeStringBlock(tlv::ParameterKey, ChallengeEmail::PARAMETER_KEY_CODE));
@@ -139,7 +139,7 @@
json.put(ChallengeEmail::PARAMETER_KEY_CODE, "4567");
CaState request(Name("/ndn/site1"), "123", RequestType::NEW, Status::CHALLENGE, cert,
"email", ChallengeEmail::NEED_CODE, time::system_clock::now(),
- 3, time::seconds(3600), std::move(json), makeEmptyBlock(ndn::tlv::ContentType_Key));
+ 3, time::seconds(3600), std::move(json), makeEmptyBlock(ndn::tlv::ContentType_Key), 0);
Block paramTLV = makeEmptyBlock(tlv::EncryptedPayload);
paramTLV.push_back(makeStringBlock(tlv::ParameterKey, ChallengeEmail::PARAMETER_KEY_CODE));
diff --git a/tests/unit-tests/challenge-pin.t.cpp b/tests/unit-tests/challenge-pin.t.cpp
index 3655cca..fd61bef 100644
--- a/tests/unit-tests/challenge-pin.t.cpp
+++ b/tests/unit-tests/challenge-pin.t.cpp
@@ -57,7 +57,7 @@
secret.add(ChallengePin::PARAMETER_KEY_CODE, "12345");
CaState request(Name("/ndn/site1"), "123", RequestType::NEW, Status::CHALLENGE, cert,
"pin", ChallengePin::NEED_CODE, time::system_clock::now(),
- 3, time::seconds(3600), std::move(secret), makeEmptyBlock(ndn::tlv::ContentType_Key));
+ 3, time::seconds(3600), std::move(secret), makeEmptyBlock(ndn::tlv::ContentType_Key), 0);
Block paramTLV = makeEmptyBlock(tlv::EncryptedPayload);
paramTLV.push_back(makeStringBlock(tlv::ParameterKey, ChallengePin::PARAMETER_KEY_CODE));
@@ -79,7 +79,7 @@
secret.add(ChallengePin::PARAMETER_KEY_CODE, "12345");
CaState request(Name("/ndn/site1"), "123", RequestType::NEW, Status::CHALLENGE, cert,
"pin", ChallengePin::NEED_CODE, time::system_clock::now(),
- 3, time::seconds(3600), std::move(secret), makeEmptyBlock(ndn::tlv::ContentType_Key));
+ 3, time::seconds(3600), std::move(secret), makeEmptyBlock(ndn::tlv::ContentType_Key), 0);
Block paramTLV = makeEmptyBlock(tlv::EncryptedPayload);
paramTLV.push_back(makeStringBlock(tlv::ParameterKey, ChallengePin::PARAMETER_KEY_CODE));
diff --git a/tests/unit-tests/crypto-helper.t.cpp b/tests/unit-tests/crypto-helper.t.cpp
index 10e56cf..6e448c1 100644
--- a/tests/unit-tests/crypto-helper.t.cpp
+++ b/tests/unit-tests/crypto-helper.t.cpp
@@ -295,14 +295,45 @@
plaintext, plaintext + sizeof(plaintext));
}
+BOOST_AUTO_TEST_CASE(AesIV)
+{
+ const uint8_t key[] = {0xbc, 0x22, 0xf3, 0xf0, 0x5c, 0xc4, 0x0d, 0xb9,
+ 0x31, 0x1e, 0x41, 0x92, 0x96, 0x6f, 0xee, 0x92};
+ const std::string plaintext = "alongstringalongstringalongstringalongstringalongstringalongstringalongstringalongstring";
+ const std::string associatedData = "test";
+ uint32_t counter = 0;
+ auto block = encodeBlockWithAesGcm128(ndn::tlv::Content, key, (uint8_t*)plaintext.c_str(), plaintext.size(),
+ (uint8_t*)associatedData.c_str(), associatedData.size(), counter);
+ block.parse();
+ auto ivBlock = block.get(tlv::InitializationVector);
+ Buffer ivBuf(ivBlock.value(), ivBlock.value_size());
+ BOOST_CHECK_EQUAL(ivBuf.size(), 12);
+ BOOST_CHECK(ivBuf[0] >= 128);
+ BOOST_CHECK_EQUAL(ivBuf[8] + ivBuf[9] + ivBuf[10] + ivBuf[11], 0);
+ BOOST_CHECK_EQUAL(counter, 11);
+ counter = 300;
+ block = encodeBlockWithAesGcm128(ndn::tlv::ApplicationParameters, key, (uint8_t*)plaintext.c_str(), plaintext.size(),
+ (uint8_t*)associatedData.c_str(), associatedData.size(), counter);
+ block.parse();
+ ivBlock = block.get(tlv::InitializationVector);
+ Buffer ivBuf2(ivBlock.value(), ivBlock.value_size());
+ BOOST_CHECK_EQUAL(ivBuf2.size(), 12);
+ BOOST_CHECK(ivBuf2[0] < 128);
+ BOOST_CHECK_EQUAL(ivBuf2[8] + ivBuf2[9], 0);
+ BOOST_CHECK_EQUAL(ivBuf2[10], 1);
+ BOOST_CHECK_EQUAL(ivBuf2[11], 44);
+ BOOST_CHECK_EQUAL(counter, 311);
+}
+
BOOST_AUTO_TEST_CASE(BlockEncodingDecoding)
{
const uint8_t key[] = {0xbc, 0x22, 0xf3, 0xf0, 0x5c, 0xc4, 0x0d, 0xb9,
0x31, 0x1e, 0x41, 0x92, 0x96, 0x6f, 0xee, 0x92};
const std::string plaintext = "alongstringalongstringalongstringalongstringalongstringalongstringalongstringalongstring";
const std::string associatedData = "test";
+ uint32_t counter = 0;
auto block = encodeBlockWithAesGcm128(ndn::tlv::Content, key, (uint8_t*)plaintext.c_str(), plaintext.size(),
- (uint8_t*)associatedData.c_str(), associatedData.size());
+ (uint8_t*)associatedData.c_str(), associatedData.size(), counter);
auto decoded = decodeBlockWithAesGcm128(block, key, (uint8_t*)associatedData.c_str(), associatedData.size());
BOOST_CHECK_EQUAL(plaintext, std::string((char*)decoded.get<uint8_t>(), decoded.size()));
}