add EncryptionTLV Encoding and Decoding
Change-Id: I67f6f733e0a02b894e49155167600963c3b2964e
diff --git a/src/crypto-support/crypto-helper.cpp b/src/crypto-support/crypto-helper.cpp
index 297bbef..8fba982 100644
--- a/src/crypto-support/crypto-helper.cpp
+++ b/src/crypto-support/crypto-helper.cpp
@@ -22,8 +22,8 @@
#include "../logging.hpp"
#include <openssl/err.h>
-#include <openssl/pem.h>
#include <openssl/hmac.h>
+#include <openssl/pem.h>
#include <ndn-cxx/encoding/buffer-stream.hpp>
#include <ndn-cxx/security/transform/base64-decode.hpp>
@@ -81,7 +81,7 @@
}
// initializes a public key algorithm context
- if (1 != EVP_PKEY_keygen_init(context->ctx_keygen)){
+ if (1 != EVP_PKEY_keygen_init(context->ctx_keygen)) {
handleErrors("Could not init context for key generation.");
return;
}
@@ -95,21 +95,21 @@
ECDHState::~ECDHState()
{
// Contexts
- if(context->ctx_params != nullptr){
+ if (context->ctx_params != nullptr) {
EVP_PKEY_CTX_free(context->ctx_params);
}
- if(context->ctx_keygen != nullptr){
+ if (context->ctx_keygen != nullptr) {
EVP_PKEY_CTX_free(context->ctx_keygen);
}
// Keys
- if(context->privkey != nullptr){
+ if (context->privkey != nullptr) {
EVP_PKEY_free(context->privkey);
}
- if(context->peerkey != nullptr){
+ if (context->peerkey != nullptr) {
EVP_PKEY_free(context->peerkey);
}
- if(context->params != nullptr){
+ if (context->params != nullptr) {
EVP_PKEY_free(context->params);
}
}
@@ -147,9 +147,7 @@
}
std::ostringstream os;
- t::bufferSource(context->publicKey, context->publicKeyLen)
- >> t::base64Encode(false)
- >> t::streamSink(os);
+ t::bufferSource(context->publicKey, context->publicKeyLen) >> t::base64Encode(false) >> t::streamSink(os);
return os.str();
}
@@ -196,9 +194,9 @@
}
int
-ndn_compute_hmac_sha256(const uint8_t *data, const unsigned data_length,
- const uint8_t *key, const unsigned key_length,
- uint8_t *prk)
+ndn_compute_hmac_sha256(const uint8_t* data, const unsigned data_length,
+ const uint8_t* key, const unsigned key_length,
+ uint8_t* prk)
{
HMAC(EVP_sha256(), key, key_length,
(unsigned char*)data, data_length,
@@ -240,8 +238,7 @@
t::PrivateKey privKey;
privKey.loadRaw(KeyType::HMAC, prk, dig_len);
OBufferStream os;
- source >> t::signerFilter(DigestAlgorithm::SHA256, privKey)
- >> t::streamSink(os);
+ source >> t::signerFilter(DigestAlgorithm::SHA256, privKey) >> t::streamSink(os);
if (i > 1) {
source.write(prev, dig_len);
@@ -263,7 +260,7 @@
aes_gcm_128_encrypt(const uint8_t* plaintext, size_t plaintext_len, const uint8_t* associated, size_t associated_len,
const uint8_t* key, const uint8_t* iv, uint8_t* ciphertext, uint8_t* tag)
{
- EVP_CIPHER_CTX *ctx;
+ EVP_CIPHER_CTX* ctx;
int len;
int ciphertext_len;
@@ -274,7 +271,7 @@
// Initialise the encryption operation.
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr)) {
- handleErrors("Cannot initialise the encryption operation when calling EVP_EncryptInit_ex()");
+ handleErrors("Cannot initialise the encryption operation when calling EVP_EncryptInit_ex()");
}
// Set IV length if default 12 bytes (96 bits) is not appropriate
@@ -387,5 +384,5 @@
BOOST_THROW_EXCEPTION(CryptoError("Error in CRYPTO SUPPORT: " + errorInfo));
}
-} // namespace ndncert
-} // namespace ndn
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/crypto-support/crypto-helper.hpp b/src/crypto-support/crypto-helper.hpp
index f75396b..4381977 100644
--- a/src/crypto-support/crypto-helper.hpp
+++ b/src/crypto-support/crypto-helper.hpp
@@ -21,31 +21,31 @@
#ifndef NDNCERT_CRYPTO_SUPPORT_CRYPTO_HELPER_HPP
#define NDNCERT_CRYPTO_SUPPORT_CRYPTO_HELPER_HPP
-#include "certificate-request.hpp"
-#include <openssl/evp.h>
#include <openssl/ec.h>
+#include <openssl/evp.h>
+
+#include "certificate-request.hpp"
static const int INFO_LEN = 10;
-static const uint8_t INFO[] = {0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9};
+static const uint8_t INFO[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
namespace ndn {
namespace ndncert {
-struct ECDH_CTX{
+struct ECDH_CTX {
int EC_NID;
- EVP_PKEY_CTX *ctx_params;
- EVP_PKEY_CTX *ctx_keygen;
- EVP_PKEY *privkey;
- EVP_PKEY *peerkey;
- EVP_PKEY *params;
+ EVP_PKEY_CTX* ctx_params;
+ EVP_PKEY_CTX* ctx_keygen;
+ EVP_PKEY* privkey;
+ EVP_PKEY* peerkey;
+ EVP_PKEY* params;
uint8_t publicKey[256];
int publicKeyLen;
uint8_t sharedSecret[256];
int sharedSecretLen;
};
-class ECDHState
-{
+class ECDHState {
public:
ECDHState();
~ECDHState();
@@ -57,9 +57,8 @@
deriveSecret(const std::string& peerKeyStr);
unique_ptr<ECDH_CTX> context;
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
- uint8_t*
- deriveSecret(const uint8_t* peerkey, int peerKeySize);
+ PUBLIC_WITH_TESTS_ELSE_PRIVATE : uint8_t*
+ deriveSecret(const uint8_t* peerkey, int peerKeySize);
uint8_t*
getRawSelfPubKey();
@@ -68,12 +67,12 @@
int
hkdf(const uint8_t* secret, int secretLen, const uint8_t* salt,
int saltLen, uint8_t* okm, int okm_len,
- const uint8_t* info=INFO, int info_len=INFO_LEN);
+ const uint8_t* info = INFO, int info_len = INFO_LEN);
int
-ndn_compute_hmac_sha256(const uint8_t *data, const unsigned data_length,
- const uint8_t *key, const unsigned key_length,
- uint8_t *prk);
+ndn_compute_hmac_sha256(const uint8_t* data, const unsigned data_length,
+ const uint8_t* key, const unsigned key_length,
+ uint8_t* prk);
/**
* Authentication GCM 128 Encryption
@@ -112,13 +111,12 @@
void
handleErrors(const std::string& errorInfo);
-class CryptoError : public std::runtime_error
-{
+class CryptoError : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
};
-} // namespace ndncert
-} // namespace ndn
+} // namespace ndncert
+} // namespace ndn
-#endif // NDNCERT_CRYPTO_SUPPORT_CRYPTO_HELPER_HPP
+#endif // NDNCERT_CRYPTO_SUPPORT_CRYPTO_HELPER_HPP
diff --git a/src/crypto-support/enc-tlv.cpp b/src/crypto-support/enc-tlv.cpp
index 8260957..990fd62 100644
--- a/src/crypto-support/enc-tlv.cpp
+++ b/src/crypto-support/enc-tlv.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2017-2019, Regents of the University of California.
+ * Copyright (c) 2017-2020, Regents of the University of California.
*
* This file is part of ndncert, a certificate management system based on NDN.
*
@@ -20,59 +20,52 @@
#include "enc-tlv.hpp"
#include "crypto-helper.hpp"
-#include <ndn-cxx/util/random.hpp>
-#include <ndn-cxx/security/transform/stream-sink.hpp>
+
+#include <ndn-cxx/encoding/block-helpers.hpp>
#include <ndn-cxx/encoding/buffer-stream.hpp>
-#include <ndn-cxx/security/transform/buffer-source.hpp>
#include <ndn-cxx/security/transform/block-cipher.hpp>
+#include <ndn-cxx/security/transform/buffer-source.hpp>
+#include <ndn-cxx/security/transform/stream-sink.hpp>
+#include <ndn-cxx/util/random.hpp>
namespace ndn {
namespace ndncert {
-const size_t DEFAULT_IV_SIZE = 16;
-
Block
-genEncBlock(uint32_t tlv_type, const uint8_t* key, size_t keyLen, const uint8_t* payload, size_t payloadSize)
+encodeBlockWithAesGcm128(uint32_t tlv_type, const uint8_t* key, const uint8_t* payload, size_t payloadSize,
+ const uint8_t* associatedData, size_t associatedDataSize)
{
Buffer iv;
- iv.resize(DEFAULT_IV_SIZE);
+ iv.resize(12);
random::generateSecureBytes(iv.data(), iv.size());
- OBufferStream os;
- security::transform::bufferSource(payload, payloadSize)
- >> security::transform::blockCipher(BlockCipherAlgorithm::AES_CBC,
- CipherOperator::ENCRYPT,
- key, keyLen, iv.data(), iv.size())
- >> security::transform::streamSink(os);
- auto encryptedPayload = *os.buf();
-
- // create the content block
+ uint8_t* encryptedPayload = new uint8_t[payloadSize];
+ uint8_t* tag = new uint8_t[16];
+ size_t encryptedPayloadLen = aes_gcm_128_encrypt(payload, payloadSize, associatedData, associatedDataSize,
+ key, iv.data(), encryptedPayload, tag);
auto content = makeEmptyBlock(tlv_type);
- content.push_back(makeBinaryBlock(ENCRYPTED_PAYLOAD, encryptedPayload.data(), encryptedPayload.size()));
- content.push_back(makeBinaryBlock(INITIAL_VECTOR, iv.data(), iv.size()));
+ content.push_back(makeBinaryBlock(tlv_initialization_vector, iv.data(), iv.size()));
+ content.push_back(makeBinaryBlock(tlv_authentication_tag, tag, 16));
+ content.push_back(makeBinaryBlock(tlv_encrypted_payload, encryptedPayload, encryptedPayloadLen));
content.encode();
return content;
}
Buffer
-parseEncBlock(const uint8_t* key, size_t keyLen, const Block& block)
+decodeBlockWithAesGcm128(const Block& block, const uint8_t* key, const uint8_t* associatedData, size_t associatedDataSize)
{
block.parse();
- Buffer iv(block.get(INITIAL_VECTOR).value(),
- block.get(INITIAL_VECTOR).value_size());
- Buffer encryptedPayload(block.get(ENCRYPTED_PAYLOAD).value(),
- block.get(ENCRYPTED_PAYLOAD).value_size());
-
- OBufferStream os;
- security::transform::bufferSource(encryptedPayload.data(), encryptedPayload.size())
- >> security::transform::blockCipher(BlockCipherAlgorithm::AES_CBC,
- CipherOperator::DECRYPT,
- key, keyLen, iv.data(), iv.size())
- >> security::transform::streamSink(os);
-
- auto payload = *os.buf();
- return payload;
+ Buffer result;
+ result.resize(block.get(tlv_encrypted_payload).value_size());
+ int resultLen = aes_gcm_128_decrypt(block.get(tlv_encrypted_payload).value(),
+ block.get(tlv_encrypted_payload).value_size(),
+ associatedData, associatedDataSize, block.get(tlv_authentication_tag).value(),
+ key, block.get(tlv_initialization_vector).value(), result.data());
+ if (resultLen == -1 || resultLen != (int)block.get(tlv_encrypted_payload).value_size()) {
+ return Buffer();
+ }
+ return result;
}
-} // namespace ndncert
-} // namespace ndn
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/crypto-support/enc-tlv.hpp b/src/crypto-support/enc-tlv.hpp
index 07f17a5..030be07 100644
--- a/src/crypto-support/enc-tlv.hpp
+++ b/src/crypto-support/enc-tlv.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2017-2019, Regents of the University of California.
+ * Copyright (c) 2017-2020, Regents of the University of California.
*
* This file is part of ndncert, a certificate management system based on NDN.
*
@@ -21,22 +21,17 @@
#ifndef NDNCERT_CRYPTO_SUPPORT_ENC_TLV_HPP
#define NDNCERT_CRYPTO_SUPPORT_ENC_TLV_HPP
-#include <ndn-cxx/encoding/block-helpers.hpp>
+#include "../ndncert-common.hpp"
namespace ndn {
namespace ndncert {
-enum {
- ENCRYPTED_PAYLOAD = 630,
- INITIAL_VECTOR = 632,
-};
-
Block
-genEncBlock(uint32_t tlv_type, const uint8_t* key, size_t keyLen, const uint8_t* payload, size_t payloadSize);
+encodeBlockWithAesGcm128(uint32_t tlv_type, const uint8_t* key, const uint8_t* payload, size_t payloadSize,
+ const uint8_t* associatedData, size_t associatedDataSize);
Buffer
-parseEncBlock(const uint8_t* key, size_t keyLen, const Block& block);
-
+decodeBlockWithAesGcm128(const Block& block, const uint8_t* key, const uint8_t* associatedData, size_t associatedDataSize);
} // namespace ndncert
} // namespace ndn