hmac.hh 3.65 KB
Newer Older
garciay's avatar
garciay committed
/*!
 * \file      hmac.hh
 * \brief     Header file for HMAC helper methods.
 * \author    ETSI STF525
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#pragma once

#include <vector>

#include <openssl/hmac.h>
#include <openssl/objects.h>

/*!
 * \enum Supported hash algorithms
 */
enum class hash_algorithms: unsigned char {
  sha_256, /*!< HMAC with SHA-256 */
  sha_384  /*!< HMAC with SHA-384 */
}; // End of class hash_algorithms


/*!
 * \class hmac
 * \brief  This class provides description of HMAC helper methods
 */
class hmac {
  HMAC_CTX _ctx; //! HMAC context
  hash_algorithms _hash_algorithms;
public:
  /*!
   * \brief Default constructor
   *        Create a new instance of the hmac class
   * \param[in] p_hash_algorithms The hash algorithm to be used to compute the HMAC
   */
  hmac(const hash_algorithms p_hash_algorithms): _ctx{}, _hash_mod(p_hash_algorithms) { ::HMAC_CTX_init(&_ctx); };
  /*!
   * \brief Default destructor
   */
  virtual ~hmac() { ::HMAC_CTX_cleanup(&_ctx); };

  /*!
   * \inline
   * \fn int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac);
   * \brief Receive bytes formated data from the lower layers
   * \param[in] p_buffer The data used to generate the HMAC
   * \param[in] p_secret_key The secret key to used to generate the HMAC
   * \param[out] p_hmac The HMAC value based of the provided data
   * \return 0 on success, -1 otherwise
   */
  inline int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac) {
    // Sanity check
    if (p_buffer.size() == 0) {
      return -1;
    }

    return generate(p_buffer.data(), p_buffer.size(), p_secret_key.data(), p_secret_key.size(), p_hmac);
  };
  
  /*!
   * \inline
   * \fn int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac);
   * \brief Receive bytes formated data from the lower layers
   * \param[in] p_buffer The data used to generate the HMAC
   * \param[in] p_buffer_length The size of the data
   * \param[in] p_secret_key The secret key to used to generate the HMAC
   * \param[in] p_secret_key_length The size of the secret key
   * \param[out] p_hmac The HMAC value based of the provided data
   * \return 0 on success, -1 otherwise
   */
  inline int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac) {
    // Sanity check
    if ((p_buffer == nullptr) || (p_secret_key == nullptr)) {
      return -1;
    }

    if (_hash_mod == hash_algorithms::sha_256) {
      // Resize data buffer
      p_hmac.resize(64);
      // Compute the hash value
      ::HMAC_Init_ex(&_ctx, p_secret_key_length, EVP_sha256(), NULL);
      ::HMAC_Update(&_ctx, p_buffer, p_length);
      ::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()));
    } else if (_hash_mod == hash_algorithms::sha_512) {
      // Resize data buffer
      p_hmac.resize(128);
      // Compute the hash value
      ::HMAC_Init_ex(&_ctx, p_secret_key_length, EVP_sha512(), NULL);
      ::HMAC_Update(&_ctx, p_buffer, p_length);
      ::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()));
    } else { // TODO To be continued
      return -1;
    }
    return 0;
  };
}; // End of class hmac