diff --git a/src/protocol-detail/crypto-helper.cpp b/src/protocol-detail/crypto-helper.cpp
new file mode 100644
index 0000000..b83d13a
--- /dev/null
+++ b/src/protocol-detail/crypto-helper.cpp
@@ -0,0 +1,396 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2020, Regents of the University of California.
+ *
+ * This file is part of ndncert, a certificate management system based on NDN.
+ *
+ * ndncert is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License along with
+ * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndncert authors and contributors.
+ */
+
+#include "crypto-helper.hpp"
+#include <openssl/err.h>
+#include <openssl/hmac.h>
+#include <openssl/pem.h>
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+#include <ndn-cxx/encoding/buffer-stream.hpp>
+#include <ndn-cxx/security/transform/base64-decode.hpp>
+#include <ndn-cxx/security/transform/base64-encode.hpp>
+#include <ndn-cxx/security/transform/buffer-source.hpp>
+#include <ndn-cxx/security/transform/private-key.hpp>
+#include <ndn-cxx/security/transform/signer-filter.hpp>
+#include <ndn-cxx/security/transform/step-source.hpp>
+#include <ndn-cxx/security/transform/stream-sink.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+const size_t HASH_SIZE = 32;
+
+NDN_LOG_INIT(ndncert.cryptosupport);
+
+struct ECDHState::ECDH_CTX {
+  int EC_NID;
+  EVP_PKEY_CTX* ctx_params;
+  EVP_PKEY_CTX* ctx_keygen;
+  EVP_PKEY* privkey;
+  EVP_PKEY* peerkey;
+  EVP_PKEY* params;
+};
+
+ECDHState::ECDHState()
+  : m_publicKeyLen(0)
+  , m_sharedSecretLen(0)
+{
+  OpenSSL_add_all_algorithms();
+  context = std::make_unique<ECDH_CTX>();
+  context->EC_NID = NID_X9_62_prime256v1;
+
+  // Create the context for parameter generation
+  if (nullptr == (context->ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr))) {
+    handleErrors("Could not create context contexts.");
+    return;
+  }
+
+  // Initialise the parameter generation
+  if (EVP_PKEY_paramgen_init(context->ctx_params) != 1) {
+    handleErrors("Could not initialize parameter generation.");
+    return;
+  }
+
+  // We're going to use the ANSI X9.62 Prime 256v1 curve
+  if (1 != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(context->ctx_params, context->EC_NID)) {
+    handleErrors("Likely unknown elliptical curve ID specified.");
+    return;
+  }
+
+  // Create the parameter object params
+  if (!EVP_PKEY_paramgen(context->ctx_params, &context->params)) {
+    // the generated key is written to context->params
+    handleErrors("Could not create parameter object parameters.");
+    return;
+  }
+
+  // Create the context for the key generation
+  if (nullptr == (context->ctx_keygen = EVP_PKEY_CTX_new(context->params, nullptr))) {
+    //The EVP_PKEY_CTX_new() function allocates public key algorithm context using
+    //the algorithm specified in pkey and ENGINE e (in this case nullptr).
+    handleErrors("Could not create the context for the key generation");
+    return;
+  }
+
+  // initializes a public key algorithm context
+  if (1 != EVP_PKEY_keygen_init(context->ctx_keygen)) {
+    handleErrors("Could not init context for key generation.");
+    return;
+  }
+  if (1 != EVP_PKEY_keygen(context->ctx_keygen, &context->privkey)) {
+    //performs a key generation operation, the generated key is written to context->privkey.
+    handleErrors("Could not generate DHE keys in final step");
+    return;
+  }
+}
+
+ECDHState::~ECDHState()
+{
+  // Contexts
+  if (context->ctx_params != nullptr) {
+    EVP_PKEY_CTX_free(context->ctx_params);
+  }
+  if (context->ctx_keygen != nullptr) {
+    EVP_PKEY_CTX_free(context->ctx_keygen);
+  }
+
+  // Keys
+  if (context->privkey != nullptr) {
+    EVP_PKEY_free(context->privkey);
+  }
+  if (context->peerkey != nullptr) {
+    EVP_PKEY_free(context->peerkey);
+  }
+  if (context->params != nullptr) {
+    EVP_PKEY_free(context->params);
+  }
+}
+
+uint8_t*
+ECDHState::getRawSelfPubKey()
+{
+  auto privECKey = EVP_PKEY_get1_EC_KEY(context->privkey);
+
+  if (privECKey == nullptr) {
+    handleErrors("Could not get referenced key when calling EVP_PKEY_get1_EC_KEY().");
+    return nullptr;
+  }
+
+  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);
+  EC_KEY_free(privECKey);
+  if (m_publicKeyLen == 0) {
+    handleErrors("Could not convert EC_POINTS to octet string when calling EC_POINT_point2oct.");
+    return nullptr;
+  }
+
+  return m_publicKey;
+}
+
+std::string
+ECDHState::getBase64PubKey()
+{
+  namespace t = ndn::security::transform;
+
+  if (m_publicKeyLen == 0) {
+    this->getRawSelfPubKey();
+  }
+  std::ostringstream os;
+  t::bufferSource(m_publicKey, m_publicKeyLen) >> t::base64Encode(false) >> t::streamSink(os);
+  return os.str();
+}
+
+uint8_t*
+ECDHState::deriveSecret(const uint8_t* peerkey, int peerKeySize)
+{
+  auto privECKey = EVP_PKEY_get1_EC_KEY(context->privkey);
+
+  if (privECKey == nullptr) {
+    handleErrors("Could not get referenced key when calling EVP_PKEY_get1_EC_KEY()");
+    return nullptr;
+  }
+
+  auto group = EC_KEY_get0_group(privECKey);
+  auto peerPoint = EC_POINT_new(group);
+  int result = EC_POINT_oct2point(group, peerPoint, peerkey, peerKeySize, nullptr);
+  if (result == 0) {
+    EC_POINT_free(peerPoint);
+    EC_KEY_free(privECKey);
+    handleErrors("Cannot convert peer's key into a EC point when calling EC_POINT_oct2point()");
+  }
+
+  if (-1 == (m_sharedSecretLen = ECDH_compute_key(m_sharedSecret, 256, peerPoint, privECKey, nullptr))) {
+    EC_POINT_free(peerPoint);
+    EC_KEY_free(privECKey);
+    handleErrors("Cannot generate ECDH secret when calling ECDH_compute_key()");
+  }
+  EC_POINT_free(peerPoint);
+  EC_KEY_free(privECKey);
+  return m_sharedSecret;
+}
+
+uint8_t*
+ECDHState::deriveSecret(const std::string& peerKeyStr)
+{
+  namespace t = ndn::security::transform;
+
+  OBufferStream os;
+  t::bufferSource(peerKeyStr) >> t::base64Decode(false) >> t::streamSink(os);
+  auto result = os.buf();
+
+  return this->deriveSecret(result->data(), result->size());
+}
+
+int
+hmac_sha256(const uint8_t* data, const unsigned data_length,
+            const uint8_t* key, const unsigned key_length,
+            uint8_t* result)
+{
+  HMAC(EVP_sha256(), key, key_length,
+       (unsigned char*)data, data_length,
+       (unsigned char*)result, nullptr);
+  return 0;
+}
+
+// avoid dependency on OpenSSL >= 1.1
+int
+hkdf(const uint8_t* secret, int secret_len, const uint8_t* salt,
+     int salt_len, uint8_t* output, int output_len,
+     const uint8_t* info, int info_len)
+{
+  namespace t = ndn::security::transform;
+
+  // hkdf generate prk
+  uint8_t prk[HASH_SIZE];
+  if (salt_len == 0) {
+    uint8_t realSalt[HASH_SIZE] = {0};
+    hmac_sha256(secret, secret_len, realSalt, HASH_SIZE, prk);
+  }
+  else {
+    hmac_sha256(secret, secret_len, salt, salt_len, prk);
+  }
+
+  // hkdf expand
+  uint8_t prev[HASH_SIZE] = {0};
+  int done_len = 0, dig_len = HASH_SIZE, n = output_len / dig_len;
+  if (output_len % dig_len)
+    n++;
+  if (n > 255 || output == nullptr)
+    return 0;
+
+  for (int i = 1; i <= n; i++) {
+    size_t copy_len;
+    const uint8_t ctr = i;
+
+    t::StepSource source;
+    t::PrivateKey privKey;
+    privKey.loadRaw(KeyType::HMAC, prk, dig_len);
+    OBufferStream os;
+    source >> t::signerFilter(DigestAlgorithm::SHA256, privKey) >> t::streamSink(os);
+
+    if (i > 1) {
+      source.write(prev, dig_len);
+    }
+    source.write(info, info_len);
+    source.write(&ctr, 1);
+    source.end();
+
+    auto result = os.buf();
+    memcpy(prev, result->data(), dig_len);
+    copy_len = (done_len + dig_len > output_len) ? output_len - done_len : dig_len;
+    memcpy(output + done_len, prev, copy_len);
+    done_len += copy_len;
+  }
+  return done_len;
+}
+
+int
+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;
+  int len;
+  int ciphertext_len;
+
+  // Create and initialise the context
+  if (!(ctx = EVP_CIPHER_CTX_new())) {
+    handleErrors("Cannot create and initialise the context when calling EVP_CIPHER_CTX_new()");
+  }
+
+  // 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()");
+  }
+
+  // Set IV length if default 12 bytes (96 bits) is not appropriate
+  if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, nullptr)) {
+    handleErrors("Cannot set IV length when calling EVP_CIPHER_CTX_ctrl()");
+  }
+
+  // Initialise key and IV
+  if (1 != EVP_EncryptInit_ex(ctx, nullptr, nullptr, key, iv)) {
+    handleErrors("Cannot initialize key and IV when calling EVP_EncryptInit_ex()");
+  }
+
+  // Provide any AAD data. This can be called zero or more times as required
+  if (1 != EVP_EncryptUpdate(ctx, nullptr, &len, associated, associated_len)) {
+    handleErrors("Cannot set associated authentication data when calling EVP_EncryptUpdate()");
+  }
+
+  // Provide the message to be encrypted, and obtain the encrypted output.
+  // EVP_EncryptUpdate can be called multiple times if necessary
+  if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) {
+    handleErrors("Cannot encrypt when calling EVP_EncryptUpdate()");
+  }
+  ciphertext_len = len;
+
+  // Finalise the encryption. Normally ciphertext bytes may be written at
+  // this stage, but this does not occur in GCM mode
+  if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) {
+    handleErrors("Cannot finalise the encryption when calling EVP_EncryptFinal_ex()");
+  }
+  ciphertext_len += len;
+
+  // Get the tag
+  if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) {
+    handleErrors("Cannot get tag when calling EVP_CIPHER_CTX_ctrl()");
+  }
+
+  // Clean up
+  EVP_CIPHER_CTX_free(ctx);
+  return ciphertext_len;
+}
+
+int
+aes_gcm_128_decrypt(const uint8_t* ciphertext, size_t ciphertext_len, const uint8_t* associated, size_t associated_len,
+                    const uint8_t* tag, const uint8_t* key, const uint8_t* iv, uint8_t* plaintext)
+{
+  EVP_CIPHER_CTX* ctx;
+  int len;
+  int plaintext_len;
+  int ret;
+
+  // Create and initialise the context
+  if (!(ctx = EVP_CIPHER_CTX_new())) {
+    handleErrors("Cannot create and initialise the context when calling EVP_CIPHER_CTX_new()");
+  }
+
+  // Initialise the decryption operation.
+  if (!EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr)) {
+    handleErrors("Cannot initialise the decryption operation when calling EVP_DecryptInit_ex()");
+  }
+
+  // Set IV length. Not necessary if this is 12 bytes (96 bits)
+  if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, nullptr)) {
+    handleErrors("Cannot set IV length when calling EVP_CIPHER_CTX_ctrl");
+  }
+
+  // Initialise key and IV
+  if (!EVP_DecryptInit_ex(ctx, nullptr, nullptr, key, iv)) {
+    handleErrors("Cannot initialise key and IV when calling EVP_DecryptInit_ex()");
+  }
+
+  // Provide any AAD data. This can be called zero or more times as required
+  if (!EVP_DecryptUpdate(ctx, nullptr, &len, associated, associated_len)) {
+    handleErrors("Cannot set associated authentication data when calling EVP_EncryptUpdate()");
+  }
+
+  // Provide the message to be decrypted, and obtain the plaintext output.
+  // EVP_DecryptUpdate can be called multiple times if necessary
+  if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) {
+    handleErrors("Cannot decrypt when calling EVP_DecryptUpdate()");
+  }
+  plaintext_len = len;
+
+  // Set expected tag value. Works in OpenSSL 1.0.1d and later
+  if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (void*)tag)) {
+    handleErrors("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;
+  }
+}
+
+void
+handleErrors(const std::string& errorInfo)
+{
+  NDN_LOG_DEBUG("Error in CRYPTO SUPPORT " << errorInfo);
+  NDN_THROW(CryptoError("Error in CRYPTO SUPPORT: " + errorInfo));
+}
+
+} // namespace ndncert
+} // namespace ndn
