update crypto helpers
Change-Id: Ic20155d07db6ca311deb2e8705acc82da6959900
diff --git a/src/detail/crypto-helpers.cpp b/src/detail/crypto-helpers.cpp
index 2437d16..b6e9e58 100644
--- a/src/detail/crypto-helpers.cpp
+++ b/src/detail/crypto-helpers.cpp
@@ -115,7 +115,7 @@
auto ecPoint = EC_KEY_get0_public_key(privECKey);
const EC_GROUP* group = EC_KEY_get0_group(privECKey);
m_publicKeyLen = EC_POINT_point2oct(group, ecPoint, POINT_CONVERSION_COMPRESSED,
- m_publicKey, 256, nullptr);
+ m_publicKey, sizeof(m_publicKey), nullptr);
EC_KEY_free(privECKey);
if (m_publicKeyLen == 0) {
context.reset();
@@ -153,7 +153,7 @@
context.reset();
NDN_THROW(std::runtime_error("Cannot convert peer's key into a EC point when calling EC_POINT_oct2point()"));
}
- result = ECDH_compute_key(m_sharedSecret, 256, peerPoint, privECKey, nullptr);
+ result = ECDH_compute_key(m_sharedSecret, sizeof(m_sharedSecret), peerPoint, privECKey, nullptr);
if (result == -1) {
EC_POINT_free(peerPoint);
EC_KEY_free(privECKey);
@@ -181,14 +181,15 @@
const uint8_t* key, size_t key_length,
uint8_t* result)
{
- auto ret = HMAC(EVP_sha256(), key, key_length, (unsigned char*)data, data_length,
- (unsigned char*)result, nullptr);
+ auto ret = HMAC(EVP_sha256(), key, key_length,
+ static_cast<const unsigned char*>(data), data_length,
+ static_cast<unsigned char*>(result), nullptr);
if (ret == nullptr) {
NDN_THROW(std::runtime_error("Error computing HMAC when calling HMAC()"));
}
}
-int
+size_t
hkdf(const uint8_t* secret, size_t secret_len, const uint8_t* salt,
size_t salt_len, uint8_t* output, size_t output_len,
const uint8_t* info, size_t info_len)
@@ -220,7 +221,7 @@
NDN_THROW(std::runtime_error("HKDF: Cannot derive result when calling EVP_PKEY_derive()."));
}
EVP_PKEY_CTX_free(pctx);
- return (int)outLen;
+ return outLen;
}
int
@@ -303,29 +304,24 @@
EVP_CIPHER_CTX_free(ctx);
NDN_THROW(std::runtime_error("Cannot set tag value when calling EVP_CIPHER_CTX_ctrl"));
}
- // Finalise the decryption. A positive return value indicates success,
- // anything else is a failure - the plaintext is not trustworthy.
ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
- // Clean up
EVP_CIPHER_CTX_free(ctx);
if (ret > 0) {
- // Success
plaintext_len += len;
return plaintext_len;
}
else {
- // Verify failed
return -1;
}
}
Block
-encodeBlockWithAesGcm128(uint32_t tlv_type, const uint8_t* key, const uint8_t* payload, size_t payloadSize,
+encodeBlockWithAesGcm128(uint32_t tlvType, const uint8_t* key, const uint8_t* payload, size_t payloadSize,
const uint8_t* associatedData, size_t associatedDataSize, uint32_t& counter)
{
Buffer iv(12);
random::generateSecureBytes(iv.data(), iv.size());
- if (tlv_type == ndn::tlv::ApplicationParameters) {
+ if (tlvType == ndn::tlv::ApplicationParameters) {
// requester
iv[0] &= ~(1UL << 7);
}
@@ -333,16 +329,22 @@
// CA
iv[0] |= 1UL << 7;
}
- uint32_t temp = counter;
- boost::endian::native_to_big_inplace(temp);
+ uint32_t temp = boost::endian::native_to_big(counter);
std::memcpy(&iv[8], reinterpret_cast<const uint8_t*>(&temp), 4);
- counter += std::ceil(payloadSize / 8);
+ uint32_t increment = std::ceil((payloadSize + 16 - 1)/16);
+ if (std::numeric_limits<uint32_t>::max() - counter < increment) {
+ // simply set counter to be 0. Will not hurt the property of being unique.
+ counter = 0;
+ }
+ else {
+ counter += increment;
+ }
Buffer encryptedPayload(payloadSize);
uint8_t tag[16];
size_t encryptedPayloadLen = aes_gcm_128_encrypt(payload, payloadSize, associatedData, associatedDataSize,
key, iv.data(), encryptedPayload.data(), tag);
- auto content = makeEmptyBlock(tlv_type);
+ auto content = makeEmptyBlock(tlvType);
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.data(), encryptedPayloadLen));
diff --git a/src/detail/crypto-helpers.hpp b/src/detail/crypto-helpers.hpp
index 00b91b1..62b25c5 100644
--- a/src/detail/crypto-helpers.hpp
+++ b/src/detail/crypto-helpers.hpp
@@ -18,14 +18,19 @@
* See AUTHORS.md for complete list of ndncert authors and contributors.
*/
-#ifndef NDNCERT_PROTOCOL_DETAIL_CRYPTO_HELPER_HPP
-#define NDNCERT_PROTOCOL_DETAIL_CRYPTO_HELPER_HPP
+#ifndef NDNCERT_DETAIL_CRYPTO_HELPER_HPP
+#define NDNCERT_DETAIL_CRYPTO_HELPER_HPP
#include "ndncert-common.hpp"
namespace ndn {
namespace ndncert {
+/**
+ * @brief State for ECDH.
+ *
+ * The ECDH is based on prime256v1.
+ */
class ECDHState
{
public:
@@ -67,9 +72,9 @@
* @param output_len The length of expected output.
* @param info The additional information used in HKDF.
* @param info_len The length of the additional information.
- * @return int The length of the derived key if successful, -1 if failed.
+ * @return size_t The length of the derived key if successful.
*/
-int
+size_t
hkdf(const uint8_t* secret, size_t secret_len,
const uint8_t* salt, size_t salt_len,
uint8_t* output, size_t output_len,
@@ -135,11 +140,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.
+ * @param counter An opaque counter that must be passed to subsequent invocations of this function
+ * with the same @param key.
* @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,
+encodeBlockWithAesGcm128(uint32_t tlvType, const uint8_t* key, const uint8_t* payload, size_t payloadSize,
const uint8_t* associatedData, size_t associatedDataSize, uint32_t& counter);
/**
@@ -158,4 +164,4 @@
} // namespace ndncert
} // namespace ndn
-#endif // NDNCERT_PROTOCOL_DETAIL_CRYPTO_HELPER_HPP
+#endif // NDNCERT_DETAIL_CRYPTO_HELPER_HPP
diff --git a/tests/unit-tests/crypto-helper.t.cpp b/tests/unit-tests/crypto-helper.t.cpp
index 8f10361..1d86e2c 100644
--- a/tests/unit-tests/crypto-helper.t.cpp
+++ b/tests/unit-tests/crypto-helper.t.cpp
@@ -309,7 +309,7 @@
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);
+ BOOST_CHECK_EQUAL(counter, 6);
counter = 300;
block = encodeBlockWithAesGcm128(ndn::tlv::ApplicationParameters, key, (uint8_t*)plaintext.c_str(), plaintext.size(),
(uint8_t*)associatedData.c_str(), associatedData.size(), counter);
@@ -321,7 +321,7 @@
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_CHECK_EQUAL(counter, 306);
}
BOOST_AUTO_TEST_CASE(BlockEncodingDecoding)