LibItsSecurity_externals.cc 75.6 KB
Newer Older
#include "LibItsSecurity_Functions.hh"

garciay's avatar
garciay committed
#include "sha256.hh"
#include "sha384.hh"
#include "hmac.hh"

garciay's avatar
garciay committed
#include "security_ecc.hh"
garciay's avatar
garciay committed

garciay's avatar
garciay committed
#include "security_services.hh"

#include <openssl/ec.h>
#include <openssl/ecdsa.h>
garciay's avatar
garciay committed

#include "loggers.hh"
namespace LibItsSecurity__Functions 
{

  // FIXME Unify code with security_services
  
garciay's avatar
garciay committed
  /**
   * \fn OCTETSTRING fx_hashWithSha256(const OCTETSTRING& p__toBeHashedData);
   * \brief Produces a 256-bit (32-byte) hash value
   * \param[in] p__toBeHashedData The data to be used to calculate the hash value
   * \return  The hash value
   */
garciay's avatar
garciay committed
  OCTETSTRING fx__hashWithSha256(
                                 const OCTETSTRING& p__toBeHashedData
                                 ) {
    sha256 hash;
garciay's avatar
garciay committed
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeHashedData), p__toBeHashedData.lengthof() + static_cast<const unsigned char *>(p__toBeHashedData));
garciay's avatar
garciay committed
    std::vector<unsigned char> hashData;
garciay's avatar
garciay committed
    hash.generate(tbh, hashData);
garciay's avatar
garciay committed
    return OCTETSTRING(hashData.size(), hashData.data());
  } // End of function fx__hashWithSha256

  /**
   * \fn OCTETSTRING fx_hashWithSha384(const OCTETSTRING& p__toBeHashedData);
   * \brief Produces a 384-bit (48-byte) hash value
   * \param[in] p__toBeHashedData Data to be used to calculate the hash value
   * \return The hash value
   */
garciay's avatar
garciay committed
  OCTETSTRING fx__hashWithSha384(
                                 const OCTETSTRING& p__toBeHashedData
                                 ) {
    sha384 hash;
garciay's avatar
garciay committed
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeHashedData), p__toBeHashedData.lengthof() + static_cast<const unsigned char *>(p__toBeHashedData));
garciay's avatar
garciay committed
    std::vector<unsigned char> hashData;
garciay's avatar
garciay committed
    hash.generate(tbh, hashData);
garciay's avatar
garciay committed
    return OCTETSTRING(hashData.size(), hashData.data());
  } // End of function fx__hashWithSha384

garciay's avatar
garciay committed
  /**
   * \fn OCTETSTRING fx__signWithEcdsaNistp256WithSha256(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
garciay's avatar
garciay committed
  OCTETSTRING fx__signWithEcdsaNistp256WithSha256(
                                                  const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                  const OCTETSTRING& p__certificateIssuer,
garciay's avatar
garciay committed
                                                  const OCTETSTRING& p__privateKey
garciay's avatar
garciay committed
                                                  ) {
    if (p__certificateIssuer.lengthof() != 32) {
      loggers::get_instance().log("fx__signWithEcdsaNistp256WithSha256: Wrong parameters");
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
garciay's avatar
garciay committed
    sha256 hash;
    std::vector<unsigned char> hashData1; // Hash (Data input)
garciay's avatar
garciay committed
    std::vector<unsigned char> tbs(static_cast<const unsigned char *>(p__toBeSignedSecuredMessage), p__toBeSignedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeSignedSecuredMessage));
    hash.generate(tbs, hashData1);
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
garciay's avatar
garciay committed
    // Calculate the signature
garciay's avatar
garciay committed
    std::vector<unsigned char> p_key(static_cast<const unsigned char *>(p__privateKey), static_cast<const unsigned char *>(p__privateKey) + p__privateKey.lengthof());
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::nist_p_256, p_key);
garciay's avatar
garciay committed
    std::vector<unsigned char> r_sig;
    std::vector<unsigned char> s_sig;
    if (k.sign(hashData, r_sig, s_sig) == 0) {
      OCTETSTRING os(r_sig.size(), r_sig.data());
      // loggers::get_instance().log_to_hexa("r_sig= ", os); 
      // loggers::get_instance().log_to_hexa("s_sig= ", OCTETSTRING(s_sig.size(), s_sig.data()); 
      os += OCTETSTRING(s_sig.size(), s_sig.data());
      // loggers::get_instance().log_to_hexa("sig= ", os); 
garciay's avatar
garciay committed
      return os;
    }

    return OCTETSTRING();
  }
garciay's avatar
garciay committed
  /**
   * \fn OCTETSTRING fx__signWithEcdsaBrainpoolp256WithSha256(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
garciay's avatar
garciay committed
  OCTETSTRING fx__signWithEcdsaBrainpoolp256WithSha256(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__certificateIssuer,
garciay's avatar
garciay committed
                                                       const OCTETSTRING& p__privateKey
garciay's avatar
garciay committed
                                                       ) {
    if (p__certificateIssuer.lengthof() != 32) {
      loggers::get_instance().log("fx__signWithEcdsaBrainpoolp256WithSha256: Wrong parameters");
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
garciay's avatar
garciay committed
    sha256 hash;
    std::vector<unsigned char> hashData1; // Hash (Data input)
garciay's avatar
garciay committed
    std::vector<unsigned char> tbs(static_cast<const unsigned char *>(p__toBeSignedSecuredMessage), p__toBeSignedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeSignedSecuredMessage));
    hash.generate(tbs, hashData1);
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
garciay's avatar
garciay committed
    // Calculate the signature
garciay's avatar
garciay committed
    std::vector<unsigned char> p_key(static_cast<const unsigned char *>(p__privateKey), static_cast<const unsigned char *>(p__privateKey) + p__privateKey.lengthof());
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, p_key);
garciay's avatar
garciay committed
    std::vector<unsigned char> r_sig;
    std::vector<unsigned char> s_sig;
    if (k.sign(hashData, r_sig, s_sig) == 0) {
      OCTETSTRING os(r_sig.size(), r_sig.data());
      // loggers::get_instance().log_to_hexa("r_sig= ", os); 
      // loggers::get_instance().log_to_hexa("s_sig= ", OCTETSTRING(s_sig.size(), s_sig.data()); 
      os += OCTETSTRING(s_sig.size(), s_sig.data());
      // loggers::get_instance().log_to_hexa("sig= ", os); 
garciay's avatar
garciay committed
      return os;
    }

    return OCTETSTRING();
  }

  /**
   * \fn OCTETSTRING fx__signWithEcdsaBrainpoolp384WithSha384(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
garciay's avatar
garciay committed
  OCTETSTRING fx__signWithEcdsaBrainpoolp384WithSha384(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__certificateIssuer,
garciay's avatar
garciay committed
                                                       const OCTETSTRING& p__privateKey
garciay's avatar
garciay committed
                                                       ) {
    if (p__certificateIssuer.lengthof() != 48) {
      loggers::get_instance().log("fx__signWithEcdsaBrainpoolp384WithSha384: Wrong parameters");
    // Calculate the SHA384 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
garciay's avatar
garciay committed
    sha384 hash;
    std::vector<unsigned char> hashData1; // Hash (Data input)
garciay's avatar
garciay committed
    std::vector<unsigned char> tbs(static_cast<const unsigned char *>(p__toBeSignedSecuredMessage), p__toBeSignedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeSignedSecuredMessage));
    hash.generate(tbs, hashData1);
    if (p__certificateIssuer != int2oct(0, 48)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
garciay's avatar
garciay committed
    // Calculate the signature
garciay's avatar
garciay committed
    std::vector<unsigned char> p_key(static_cast<const unsigned char *>(p__privateKey), static_cast<const unsigned char *>(p__privateKey) + p__privateKey.lengthof());
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, p_key);
garciay's avatar
garciay committed
    std::vector<unsigned char> r_sig;
    std::vector<unsigned char> s_sig;
    if (k.sign(hashData, r_sig, s_sig) == 0) {
      OCTETSTRING os(r_sig.size(), r_sig.data());
      //loggers::get_instance().log_to_hexa("fx__signWithEcdsaBrainpoolp384WithSha384: r_sig= ", os); 
      //loggers::get_instance().log_to_hexa("fx__signWithEcdsaBrainpoolp384WithSha384: s_sig= ", OCTETSTRING(s_sig.size(), s_sig.data())); 
garciay's avatar
garciay committed
      os += OCTETSTRING(s_sig.size(), s_sig.data());
      //loggers::get_instance().log_to_hexa("fx__signWithEcdsaBrainpoolp384WithSha384: sig= ", os); 
garciay's avatar
garciay committed
      return os;
    }

    return OCTETSTRING();
  }

garciay's avatar
garciay committed
  /**
   * \fn BOOLEAN fx__verifyWithEcdsaNistp256WithSha256(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaNistp256PublicKeyCompressed);
   * \brief Verify the signature of the specified data
   * \param[in] p__toBeVerifiedData The data to be verified
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaNistp256PublicKeyCompressed The compressed public key (x coordinate only)
   * \return true on success, false otherwise
   */
garciay's avatar
garciay committed
  BOOLEAN fx__verifyWithEcdsaNistp256WithSha256(
                                                const OCTETSTRING& p__toBeVerifiedData,
                                                const OCTETSTRING& p__certificateIssuer,
garciay's avatar
garciay committed
                                                const OCTETSTRING& p__signature,
                                                const OCTETSTRING& p__ecdsaNistp256PublicKeyCompressed,
                                                const INTEGER& p__compressedMode
garciay's avatar
garciay committed
                                                ) {
    if (p__certificateIssuer.lengthof() != 32) {
      loggers::get_instance().log("fx__verifyWithEcdsaNistp256WithSha256: Wrong parameters");
      return FALSE;
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
garciay's avatar
garciay committed
    sha256 hash;
    std::vector<unsigned char> hashData1; // Hash (Data input)
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), p__toBeVerifiedData.lengthof() + static_cast<const unsigned char *>(p__toBeVerifiedData));
    hash.generate(tbh, hashData1);
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
garciay's avatar
garciay committed
    // Check the signature
garciay's avatar
garciay committed
    std::vector<unsigned char> signature(static_cast<const unsigned char *>(p__signature), static_cast<const unsigned char *>(p__signature) + p__signature.lengthof());
    std::vector<unsigned char> pub_key_compressed(static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyCompressed), static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyCompressed) + p__ecdsaNistp256PublicKeyCompressed.lengthof());
    security_ecc k(ec_elliptic_curves::nist_p_256, pub_key_compressed, (p__compressedMode == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (k.sign_verif(hashData, signature) == 0) {
      return TRUE;
    }

    return FALSE;
  }
  
  /**
   * \fn BOOLEAN fx__verifyWithEcdsaNistp256WithSha256_1(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaNistp256PublicKeyX, const OCTETSTRING& p__ecdsaNistp256PublicKeyY);
   * \brief Verify the signature of the specified data
   * \param[in] p__toBeVerifiedData The data to be verified
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaNistp256PublicKeyX The public key (x coordinate)
   * \param[in] p__ecdsaNistp256PublicKeyY The public key (y coordinate)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaNistp256WithSha256__1(
                                                   const OCTETSTRING& p__toBeVerifiedData,
                                                   const OCTETSTRING& p__certificateIssuer,
                                                   const OCTETSTRING& p__signature,
                                                   const OCTETSTRING& p__ecdsaNistp256PublicKeyX,
                                                   const OCTETSTRING& p__ecdsaNistp256PublicKeyY
                                                   ) {
    if (p__certificateIssuer.lengthof() != 32) {
      loggers::get_instance().log("fx__verifyWithEcdsaNistp256WithSha256__1: Wrong parameters");
      return FALSE;
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    std::vector<unsigned char> hashData1; // Hash (Data input)
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), p__toBeVerifiedData.lengthof() + static_cast<const unsigned char *>(p__toBeVerifiedData));
    hash.generate(tbh, hashData1);
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
    // Check the signature
    std::vector<unsigned char> signature(static_cast<const unsigned char *>(p__signature), static_cast<const unsigned char *>(p__signature) + p__signature.lengthof());
garciay's avatar
garciay committed
    std::vector<unsigned char> pub_key_x(static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyX), static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyX) + p__ecdsaNistp256PublicKeyX.lengthof());
    std::vector<unsigned char> pub_key_y(static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyY), static_cast<const unsigned char *>(p__ecdsaNistp256PublicKeyY) + p__ecdsaNistp256PublicKeyY.lengthof());
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::nist_p_256, pub_key_x, pub_key_y);
    //security_ecc k(ec_elliptic_curves::nist_p_256);
garciay's avatar
garciay committed
    if (k.sign_verif(hashData, signature) == 0) {
      return TRUE;
garciay's avatar
garciay committed
    return FALSE;
garciay's avatar
garciay committed
  }
garciay's avatar
garciay committed
  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyCompressed);
   * \brief Verify the signature of the specified data
   * \param[in] p__toBeVerifiedData The data to be verified
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp256PublicKeyCompressed The compressed public key (x coordinate only)
   * \return true on success, false otherwise
   */
garciay's avatar
garciay committed
  BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256(
                                                     const OCTETSTRING& p__toBeVerifiedData,
                                                     const OCTETSTRING& p__certificateIssuer,
garciay's avatar
garciay committed
                                                     const OCTETSTRING& p__signature,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyCompressed,
                                                     const INTEGER& p__compressedMode
garciay's avatar
garciay committed
                                                     ) {
    if (p__certificateIssuer.lengthof() != 32) {
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp256WithSha256: Wrong parameters");
      return FALSE;
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
garciay's avatar
garciay committed
    sha256 hash;
    std::vector<unsigned char> hashData1; // Hash (Data input)
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), p__toBeVerifiedData.lengthof() + static_cast<const unsigned char *>(p__toBeVerifiedData));
    hash.generate(tbh, hashData1);
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
garciay's avatar
garciay committed
    // Check the signature
garciay's avatar
garciay committed
    std::vector<unsigned char> signature(static_cast<const unsigned char *>(p__signature), static_cast<const unsigned char *>(p__signature) + p__signature.lengthof());
    std::vector<unsigned char> pub_key_compressed(static_cast<const unsigned char *>(p__ecdsaBrainpoolp256PublicKeyCompressed), static_cast<const unsigned char *>(p__ecdsaBrainpoolp256PublicKeyCompressed) + p__ecdsaBrainpoolp256PublicKeyCompressed.lengthof());
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, pub_key_compressed, (p__compressedMode == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (k.sign_verif(hashData, signature) == 0) {
      return TRUE;
    }

    return FALSE;
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256_1(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyX, const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyY);
   * \brief Verify the signature of the specified data
   * \param[in] p__toBeVerifiedData The data to be verified
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp256PublicKeyX The public key (x coordinate)
   * \param[in] p__ecdsaBrainpoolp256PublicKeyY The public key (y coordinate)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256__1(
                                                        const OCTETSTRING& p__toBeVerifiedData,
		                                                const OCTETSTRING& p__certificateIssuer,
                                                        const OCTETSTRING& p__signature,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyX,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyY
                                                        ) {
    if (p__certificateIssuer.lengthof() != 32) {
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp256WithSha256__1: Wrong parameters");
      return FALSE;
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    std::vector<unsigned char> hashData1; // Hash (Data input)
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), p__toBeVerifiedData.lengthof() + static_cast<const unsigned char *>(p__toBeVerifiedData));
    hash.generate(tbh, hashData1);
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
    // Check the signature
    std::vector<unsigned char> signature(static_cast<const unsigned char *>(p__signature), static_cast<const unsigned char *>(p__signature) + p__signature.lengthof());
garciay's avatar
garciay committed
    std::vector<unsigned char> pub_key_x(static_cast<const unsigned char *>(p__ecdsaBrainpoolp256PublicKeyX), static_cast<const unsigned char *>(p__ecdsaBrainpoolp256PublicKeyX) + p__ecdsaBrainpoolp256PublicKeyX.lengthof());
    std::vector<unsigned char> pub_key_y(static_cast<const unsigned char *>(p__ecdsaBrainpoolp256PublicKeyY), static_cast<const unsigned char *>(p__ecdsaBrainpoolp256PublicKeyY) + p__ecdsaBrainpoolp256PublicKeyY.lengthof());
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, pub_key_x, pub_key_y);
garciay's avatar
garciay committed
    if (k.sign_verif(hashData, signature) == 0) {
      return TRUE;
    }

    return FALSE;
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyCompressed);
   * \brief Verify the signature of the specified data
   * \param[in] p__toBeVerifiedData The data to be verified
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp384PublicKeyCompressed The compressed public key (x coordinate only)
   * \return true on success, false otherwise
   */
garciay's avatar
garciay committed
  BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384(
                                                     const OCTETSTRING& p__toBeVerifiedData,
                                                     const OCTETSTRING& p__certificateIssuer,
garciay's avatar
garciay committed
                                                     const OCTETSTRING& p__signature,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyCompressed,
                                                     const INTEGER& p__compressedMode
garciay's avatar
garciay committed
                                                     ) {
    if (p__certificateIssuer.lengthof() != 48) {
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp384WithSha384: Wrong parameters");
      return FALSE;
    // Calculate the SHA384 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
garciay's avatar
garciay committed
    sha384 hash;
    std::vector<unsigned char> hashData1; // Hash (Data input)
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), p__toBeVerifiedData.lengthof() + static_cast<const unsigned char *>(p__toBeVerifiedData));
    hash.generate(tbh, hashData1);
    if (p__certificateIssuer != int2oct(0, 48)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
garciay's avatar
garciay committed
    // Check the signature
garciay's avatar
garciay committed
    std::vector<unsigned char> signature(static_cast<const unsigned char *>(p__signature), static_cast<const unsigned char *>(p__signature) + p__signature.lengthof());
    std::vector<unsigned char> pub_key_compressed(static_cast<const unsigned char *>(p__ecdsaBrainpoolp384PublicKeyCompressed), static_cast<const unsigned char *>(p__ecdsaBrainpoolp384PublicKeyCompressed) + p__ecdsaBrainpoolp384PublicKeyCompressed.lengthof());
    security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, pub_key_compressed, (p__compressedMode == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (k.sign_verif(hashData, signature) == 0) {
      return TRUE;
    }

    return FALSE;
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384_1(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyX, const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyY);
   * \brief Verify the signature of the specified data
   * \param[in] p__toBeVerifiedData The data to be verified
   * \param[in] p__certificateIssuer Certificate issuer
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
   * \param[in] p__ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384__1(
                                                        const OCTETSTRING& p__toBeVerifiedData,
		                                                const OCTETSTRING& p__certificateIssuer,
                                                        const OCTETSTRING& p__signature,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyX,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyY
                                                        ) {
    if (p__certificateIssuer.lengthof() != 48) {
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp384WithSha384__1: Wrong parameters");
      return FALSE;
    // Calculate the SHA384 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    std::vector<unsigned char> hashData1; // Hash (Data input)
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), p__toBeVerifiedData.lengthof() + static_cast<const unsigned char *>(p__toBeVerifiedData));
    hash.generate(tbh, hashData1);
    if (p__certificateIssuer != int2oct(0, 48)) { // || Hash (Signer identifier input)
      std::vector<unsigned char> issuer = std::vector<unsigned char>(static_cast<const unsigned char*>(p__certificateIssuer), p__certificateIssuer.lengthof() + static_cast<const unsigned char*>(p__certificateIssuer));
      hashData1.insert(hashData1.end(), issuer.cbegin(), issuer.cend());
    std::vector<unsigned char> hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
    // Check the signature
    std::vector<unsigned char> signature(static_cast<const unsigned char *>(p__signature), static_cast<const unsigned char *>(p__signature) + p__signature.lengthof());
garciay's avatar
garciay committed
    std::vector<unsigned char> pub_key_x(static_cast<const unsigned char *>(p__ecdsaBrainpoolp384PublicKeyX), static_cast<const unsigned char *>(p__ecdsaBrainpoolp384PublicKeyX) + p__ecdsaBrainpoolp384PublicKeyX.lengthof());
    std::vector<unsigned char> pub_key_y(static_cast<const unsigned char *>(p__ecdsaBrainpoolp384PublicKeyY), static_cast<const unsigned char *>(p__ecdsaBrainpoolp384PublicKeyY) + p__ecdsaBrainpoolp384PublicKeyY.lengthof());
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, pub_key_x, pub_key_y);
garciay's avatar
garciay committed
    if (k.sign_verif(hashData, signature) == 0) {
      return TRUE;
    }

    return FALSE;
  }
  /**
   * \fn OCTETSTRING fx__test__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m);
   * \brief Generate a HMAC-SHA256 value based on the provided secret key
   * \param[in] p__k The secret key used for the HMAC calculation
   * \param[in] p__m The message
   * \return The HMAC value resized to 16-byte
   */
  OCTETSTRING fx__test__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m) {
    loggers::get_instance().log(">>> fx__test__hmac__sha256");

    hmac h(hash_algorithms::sha_256); // TODO Use ec_encryption_algorithm
    std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k));
    std::vector<unsigned char> m(static_cast<const unsigned char *>(p__m), p__m.lengthof() + static_cast<const unsigned char *>(p__m));
    std::vector<unsigned char> t;
    if (h.generate(m, k, t) == -1) {
      loggers::get_instance().warning("fx__test__hmac__sha256: Failed to generate HMAC");
      return OCTETSTRING();
    }

    OCTETSTRING os(t.size(), t.data());
    loggers::get_instance().log_to_hexa("fx__test__hmac__sha256: HMAC: ", os);

    return os;
  }

  /**
   * \fn OCTETSTRING fx__test__encrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt);
   * \brief Encrypt the message using AES 128 CCM algorithm
   * \param[in] p__k The symmetric encryption key
   * \param[in] p__n The initial vector, nonce vector
   * \param[in] p__pt The message to encrypt
   * \return The encrypted message concatenated to the AES 128 CCM tag
   */
  OCTETSTRING fx__test__encrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt) {
    loggers::get_instance().log(">>> fx__test__encrypt__aes__128__ccm__test");
    
garciay's avatar
garciay committed
    security_ecc ec(ec_elliptic_curves::nist_p_256);
    std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k));
    std::vector<unsigned char> n(static_cast<const unsigned char *>(p__n), p__n.lengthof() + static_cast<const unsigned char *>(p__n));
    std::vector<unsigned char> pt(static_cast<const unsigned char *>(p__pt), p__pt.lengthof() + static_cast<const unsigned char *>(p__pt));

garciay's avatar
garciay committed
    std::vector<unsigned char> enc_message;
    if (ec.encrypt(encryption_algotithm::aes_128_ccm, k, n, pt, enc_message) == -1) {
      loggers::get_instance().warning("fx__test__encrypt__aes__128__ccm__test: Failed to encrypt message");
garciay's avatar
garciay committed
      return OCTETSTRING();
    }
    OCTETSTRING os(enc_message.size(), enc_message.data());
    os = os + OCTETSTRING(ec.tag().size(), ec.tag().data());
    loggers::get_instance().log_to_hexa("fx__test__encrypt__aes__128__ccm__test: encrypted message: ", os);

    return os;
  }
  
   * \fn OCTETSTRING fx__test__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct);
   * \brief Encrypt the message using AES 128 CCM algorithm
   * \param[in] p__k The symmetric encryption key
   * \param[in] p__n The initial vector, nonce vector
   * \param[in] p__ct The encrypted message concatenated to the AES 128 CCM tag
   * \return The original message
   */
  OCTETSTRING fx__test__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct) {
    loggers::get_instance().log(">>> fx__test__decrypt__aes__128__ccm__test");
    
    security_ecc ec(ec_elliptic_curves::nist_p_256);
    std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k));
    std::vector<unsigned char> n(static_cast<const unsigned char *>(p__n), p__n.lengthof() + static_cast<const unsigned char *>(p__n));
    std::vector<unsigned char> ct(static_cast<const unsigned char *>(p__ct), p__ct.lengthof() + static_cast<const unsigned char *>(p__ct));
    // Extract the tag
    std::vector<unsigned char> tag(16, 0x00);
    std::copy(ct.end() - tag.size(), ct.end(), tag.begin());
    loggers::get_instance().log_to_hexa("fx__test__decrypt__aes__128__ccm__test: tag: ", tag.data(), tag.size());
    // Remove the tag from the end of the encrypted message
    ct.resize(ct.size() - tag.size());
    
    std::vector<unsigned char> message;
    if (ec.decrypt(encryption_algotithm::aes_128_ccm, k, n, tag, ct, message) == -1) {
      loggers::get_instance().warning("fx__test__decrypt__aes__128__ccm__test: Failed to decrypt message");
      return OCTETSTRING();
    }
    OCTETSTRING os(message.size(), message.data());
    loggers::get_instance().log_to_hexa("fx__test__decrypt__aes__128__ccm__test: decrypted message: ", os);
    
    return os;
  }
  
  /**
   * \fn OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyX, const OCTETSTRING& p__recipientsPublicKeyY, OCTETSTRING& p__publicEphemeralKeyX, OCTETSTRING& p__publicEphemeralKeyY, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce);
   * \brief Encrypt the message using ECIES algorithm to encrypt AES 128 CCM symmetric key, as defined in IEEE Std 1609.2-2017
   * \param[in] p__toBeEncryptedSecuredMessage The message to be encrypted
   * \param[in] p__recipientsPublicKeyCompressed The Recipient's compressed public key
   * \param[in] p__compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
   * \param[out] p__publicEphemeralKeyCompressed The public ephemeral compressed key
   * \param[out] p__ephemeralCompressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
   * \param[out] p__encrypted__sym__key The encrypted AES 128 symmetric key
   * \param[out] p__authentication__vector The tag of the encrypted AES 128 symmetric key
   * \param[out] p__nonce The nonce vector
   * \return The original message
   * \see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
   * \see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
   * \see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
   */
  // TODO Use common function for both fx__encryptWithEciesxxx and fx__decryptWithEciesxxx function
  OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyCompressed, const INTEGER& p__compressedMode, OCTETSTRING& p__publicEphemeralKeyCompressed, INTEGER& p__ephemeralCompressedMode, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce) {
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__toBeEncryptedSecuredMessage);
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__recipientsPublicKeyX: ", p__recipientsPublicKeyCompressed);
    loggers::get_instance().log(">>> fx__encryptWithEciesNistp256WithSha256: p__compressedMode: %d", static_cast<int>(p__compressedMode));
    
    // 1. Generate new Private/Public key
    security_ecc ec(ec_elliptic_curves::nist_p_256);
    if (ec.generate() == -1) {
      loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate ephemeral keys");
      return OCTETSTRING();
    }
    // 2. Generate and derive shared secret
    std::vector<unsigned char> recipients_public_comp_key(static_cast<const unsigned char *>(p__recipientsPublicKeyCompressed), p__recipientsPublicKeyCompressed.lengthof() + static_cast<const unsigned char *>(p__recipientsPublicKeyCompressed));
    security_ecc ec_comp(ec_elliptic_curves::nist_p_256, recipients_public_comp_key, (static_cast<int>(p__compressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y()) == -1) {
      loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate and derive secret key");
      return OCTETSTRING();
    }
    // Set the encrypted symmetric key
    p__encrypted__sym__key = OCTETSTRING(ec.encrypted_symmetric_key().size(), ec.encrypted_symmetric_key().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Encrypted symmetric key: ", p__encrypted__sym__key);
    // Set the tag of the symmetric key encryption
    p__authentication__vector = OCTETSTRING(ec.tag().size(), ec.tag().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    // Set ephemeral public keys
    p__publicEphemeralKeyCompressed = OCTETSTRING(ec.public_key_compressed().size(), ec.public_key_compressed().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public compressed key: ", p__publicEphemeralKeyCompressed);
    p__ephemeralCompressedMode = (ec.public_key_compressed_mode() == ecc_compressed_mode::compressed_y_0) ? 0 : 1;
    loggers::get_instance().log("fx__encryptWithEciesNistp256WithSha256: Ephemeral public compressed mode: %d: ", p__ephemeralCompressedMode);
    // 3. Retrieve AES 128 parameters
    p__nonce = OCTETSTRING(ec.nonce().size(), ec.nonce().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce);
    OCTETSTRING enc_symm_key = OCTETSTRING(ec.symmetric_encryption_key().size(), ec.symmetric_encryption_key().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc_symm_key: ", enc_symm_key);
    // 4. Encrypt the data using AES-128 CCM
    std::vector<unsigned char> message(static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage), p__toBeEncryptedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage));
    std::vector<unsigned char> enc_message;
    if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), message, enc_message) == -1) {
garciay's avatar
garciay committed
      loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message");
      return OCTETSTRING();
garciay's avatar
garciay committed
    }
    enc_message.insert(enc_message.end(), std::make_move_iterator(ec.tag().begin()), std::make_move_iterator(ec.tag().end()));
    OCTETSTRING os(enc_message.size(), enc_message.data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc message||Tag: ", os);
    
  /**
   * \fn OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyX, const OCTETSTRING& p__publicEphemeralKeyY, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce);
   * \brief Decrypt the message using ECIES algorithm to decrypt AES 128 CCM symmetric key, as defined in IEEE Std 1609.2-2017
   * \param[in] p__encryptedSecuredMessage The encrypted message
   * \param[in] p__privateEncKey The private encryption key
   * \param[in] p__publicEphemeralKeyCompressed The public ephemeral compressed key
   * \param[in] p__ephemeralCompressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
   * \param[in] p__encrypted__sym__key The encrypted AES 128 symmetric key
   * \param[in] p__authentication__vector The tag of the encrypted AES 128 symmetric key
   * \param[in] p__nonce The nonce vector
   * \return The original message
   * \see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
   * \see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
   * \see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
   */
  // TODO Use common function for both fx__encryptWithEciesxxx and fx__decryptWithEciesxxx function
  OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyCompressed, const INTEGER& p__ephemeralCompressedMode, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce) {
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__privateEncKey: ", p__privateEncKey);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__publicEphemeralKeyCompressed: ", p__publicEphemeralKeyCompressed);
    loggers::get_instance().log(">>> fx__decryptWithEciesNistp256WithSha256: p__ephemeralCompressedMode: %d", static_cast<int>(p__ephemeralCompressedMode));
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
    // 1. Create security_ecc instance
    std::vector<unsigned char> private_enc_key(static_cast<const unsigned char*>(p__privateEncKey), p__privateEncKey.lengthof() + static_cast<const unsigned char*>(p__privateEncKey));
    security_ecc ec(ec_elliptic_curves::nist_p_256, private_enc_key);
    std::vector<unsigned char> ephemeral_public_comp_key(static_cast<const unsigned char*>(p__publicEphemeralKeyCompressed), p__publicEphemeralKeyCompressed.lengthof() + static_cast<const unsigned char*>(p__publicEphemeralKeyCompressed));
    security_ecc ec_comp(ec_elliptic_curves::nist_p_256, ephemeral_public_comp_key, (static_cast<int>(p__ephemeralCompressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    // 2. Generate the shared secret value based on recipient's public ephemeral keys will be required
    std::vector<unsigned char> enc_sym_key(static_cast<const unsigned char*>(p__encrypted__sym__key), p__encrypted__sym__key.lengthof() + static_cast<const unsigned char*>(p__encrypted__sym__key));
    std::vector<unsigned char> nonce(static_cast<const unsigned char*>(p__nonce), p__nonce.lengthof() + static_cast<const unsigned char*>(p__nonce));
    std::vector<unsigned char> authentication_vector(static_cast<const unsigned char*>(p__authentication__vector), p__authentication__vector.lengthof() + static_cast<const unsigned char*>(p__authentication__vector));
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, private_enc_key, ec_comp.public_key_x(), ec_comp.public_key_y(), enc_sym_key, nonce, authentication_vector) == -1) {
      loggers::get_instance().warning("fx__decryptWithEciesNistp256WithSha256: Failed to generate shared secret");
      return OCTETSTRING();
    }
    // Decrypt the message
    std::vector<unsigned char> enc_message(static_cast<const unsigned char*>(p__encryptedSecuredMessage), p__encryptedSecuredMessage.lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p__encryptedSecuredMessage));
    loggers::get_instance().log_to_hexa("fx__decryptWithEciesNistp256WithSha256: enc_message: ", enc_message.data(), enc_message.size());
    std::vector<unsigned char> tag(p__encryptedSecuredMessage.lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p__encryptedSecuredMessage), p__encryptedSecuredMessage.lengthof() + static_cast<const unsigned char*>(p__encryptedSecuredMessage));
    loggers::get_instance().log_to_hexa("fx__decryptWithEciesNistp256WithSha256: tag: ", tag.data(), tag.size());
    std::vector<unsigned char> message;
    if (ec.decrypt(tag, enc_message, message) == -1) {
      loggers::get_instance().warning("fx__decryptWithEciesNistp256WithSha256: Failed to generate shared secret");
      return OCTETSTRING();
    }
    
    OCTETSTRING os(message.size(), message.data());
    loggers::get_instance().log_to_hexa("fx__decryptWithEciesNistp256WithSha256: dec message: ", os);
    
    return os;
  OCTETSTRING fx__encryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyCompressed, const INTEGER& p__compressedMode, OCTETSTRING& p__publicEphemeralKeyCompressed, INTEGER& p__ephemeralCompressedMode, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce) {
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__toBeEncryptedSecuredMessage);
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__recipientsPublicKeyCompressed: ", p__recipientsPublicKeyCompressed);
    loggers::get_instance().log(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__compressedMode: %d", static_cast<int>(p__compressedMode));

    // 1. Generate new Private/Public key
    security_ecc ec(ec_elliptic_curves::brainpool_p_256_r1);
    if (ec.generate() == -1) {
      loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to generate ephemeral keys");
      return OCTETSTRING();
    }
    // 2. Generate and derive shared secret
    std::vector<unsigned char> recipients_public_comp_key(static_cast<const unsigned char *>(p__recipientsPublicKeyCompressed), p__recipientsPublicKeyCompressed.lengthof() + static_cast<const unsigned char *>(p__recipientsPublicKeyCompressed));
    security_ecc ec_comp(ec_elliptic_curves::brainpool_p_256_r1, recipients_public_comp_key, (static_cast<int>(p__compressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y()) == -1) {
      loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to generate and derive secret key");
      return OCTETSTRING();
    }
    // Set the encrypted symmetric key
    p__encrypted__sym__key = OCTETSTRING(ec.encrypted_symmetric_key().size(), ec.encrypted_symmetric_key().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesBrainpoolp256WithSha256: Encrypted symmetric key: ", p__encrypted__sym__key);
    // Set the tag of the symmetric key encryption
    p__authentication__vector = OCTETSTRING(ec.tag().size(), ec.tag().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesBrainpoolp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    // Set ephemeral public keys
    p__publicEphemeralKeyCompressed = OCTETSTRING(ec.public_key_compressed().size(), ec.public_key_compressed().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public compressed key: ", p__publicEphemeralKeyCompressed);
    p__ephemeralCompressedMode = (ec.public_key_compressed_mode() == ecc_compressed_mode::compressed_y_0) ? 0 : 1;
    loggers::get_instance().log("fx__encryptWithEciesNistp256WithSha256: Ephemeral public compressed mode: %d: ", p__ephemeralCompressedMode);
    // 3. Retrieve AES 128 parameters
    p__nonce = OCTETSTRING(ec.nonce().size(), ec.nonce().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesBrainpoolp256WithSha256: p__nonce: ", p__nonce);
    OCTETSTRING enc_symm_key = OCTETSTRING(ec.symmetric_encryption_key().size(), ec.symmetric_encryption_key().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesBrainpoolp256WithSha256: enc_symm_key: ", enc_symm_key);
    // 4. Encrypt the data using AES-128 CCM
    std::vector<unsigned char> message(static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage), p__toBeEncryptedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage));
    std::vector<unsigned char> enc_message;
    if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), message, enc_message) == -1) {
      loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to encrypt message");
      return OCTETSTRING();
    }
    enc_message.insert(enc_message.end(), std::make_move_iterator(ec.tag().begin()), std::make_move_iterator(ec.tag().end()));
    OCTETSTRING os(enc_message.size(), enc_message.data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesBrainpoolp256WithSha256: enc message||Tag: ", os);

    return os;
  }

  OCTETSTRING fx__decryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyCompressed, const INTEGER& p__ephemeralCompressedMode, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce) {
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__privateEncKey: ", p__privateEncKey);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__publicEphemeralKeyCompressed: ", p__publicEphemeralKeyCompressed);
    loggers::get_instance().log(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__ephemeralCompressedMode: %d", static_cast<int>(p__ephemeralCompressedMode));
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__nonce: ", p__nonce);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);

    // 1. Create security_ecc instance
    std::vector<unsigned char> private_enc_key(static_cast<const unsigned char*>(p__privateEncKey), p__privateEncKey.lengthof() + static_cast<const unsigned char*>(p__privateEncKey));
    security_ecc ec(ec_elliptic_curves::brainpool_p_256_r1, private_enc_key);
    std::vector<unsigned char> ephemeral_public_comp_key(static_cast<const unsigned char*>(p__publicEphemeralKeyCompressed), p__publicEphemeralKeyCompressed.lengthof() + static_cast<const unsigned char*>(p__publicEphemeralKeyCompressed));
    security_ecc ec_comp(ec_elliptic_curves::brainpool_p_256_r1, ephemeral_public_comp_key, (static_cast<int>(p__ephemeralCompressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);

    // 2. Generate the shared secret value based on recipient's public ephemeral keys will be required
    std::vector<unsigned char> enc_sym_key(static_cast<const unsigned char*>(p__encrypted__sym__key), p__encrypted__sym__key.lengthof() + static_cast<const unsigned char*>(p__encrypted__sym__key));
    std::vector<unsigned char> nonce(static_cast<const unsigned char*>(p__nonce), p__nonce.lengthof() + static_cast<const unsigned char*>(p__nonce));
    std::vector<unsigned char> authentication_vector(static_cast<const unsigned char*>(p__authentication__vector), p__authentication__vector.lengthof() + static_cast<const unsigned char*>(p__authentication__vector));
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, private_enc_key, ec_comp.public_key_x(), ec_comp.public_key_y(), enc_sym_key, nonce, authentication_vector) == -1) {
      loggers::get_instance().warning("fx__decryptWithEciesBrainpoolp256WithSha256: Failed to generate shared secret");
      return OCTETSTRING();
    }

    // Decypt the message
    std::vector<unsigned char> enc_message(static_cast<const unsigned char*>(p__encryptedSecuredMessage), p__encryptedSecuredMessage.lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p__encryptedSecuredMessage));
    loggers::get_instance().log_to_hexa("fx__decryptWithEciesBrainpoolp256WithSha256: enc_message: ", enc_message.data(), enc_message.size());
    std::vector<unsigned char> tag(p__encryptedSecuredMessage.lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p__encryptedSecuredMessage), p__encryptedSecuredMessage.lengthof() + static_cast<const unsigned char*>(p__encryptedSecuredMessage));
    loggers::get_instance().log_to_hexa("fx__decryptWithEciesBrainpoolp256WithSha256: tag: ", tag.data(), tag.size());
    std::vector<unsigned char> message;
    if (ec.decrypt(tag, enc_message, message) == -1) {
      loggers::get_instance().warning("fx__decryptWithEciesBrainpoolp256WithSha256: Failed to generate shared secret");
      return OCTETSTRING();
    }

    OCTETSTRING os(message.size(), message.data());
    loggers::get_instance().log_to_hexa("fx__decryptWithEciesBrainpoolp256WithSha256: dec message: ", os);

    return os;
  }

garciay's avatar
garciay committed
  /**
   * \brief    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
garciay's avatar
garciay committed
   *          This function should not be used by the ATS
   * \param   p_privateKey    The new private key value
   * \param   p_publicKeyX    The new public key value (x coordinate)
   * \param   p_publicKeyX    The new public key value (y coordinate)
   * \return  true on success, false otherwise
garciay's avatar
garciay committed
   fx_generateKeyPair_nistp256(out octetstring<UInt64> p_privateKey, out octetstring p_publicKeyX, out octetstring p_publicKeyY) return boolean;
garciay's avatar
garciay committed
  */
garciay's avatar
garciay committed
  BOOLEAN fx__generateKeyPair__nistp256(
                                        OCTETSTRING& p__privateKey,
                                        OCTETSTRING& p__publicKeyX,
                                        OCTETSTRING& p__publicKeyY,
                                        OCTETSTRING& p__publicKeyCompressed,
                                        INTEGER& p__compressedMode
garciay's avatar
garciay committed
                                        ) {
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::nist_p_256);
garciay's avatar
garciay committed
    if (k.generate() != 0) {
      p__privateKey = OCTETSTRING();
      p__publicKeyX = OCTETSTRING();
garciay's avatar
garciay committed
      p__publicKeyY = OCTETSTRING();
      p__publicKeyCompressed = OCTETSTRING();
garciay's avatar
garciay committed
      return FALSE;
    }
garciay's avatar
garciay committed
    // Sanity checks
    if (k.private_key().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__nistp256: Invalid private key size");
      return FALSE;
    }
    if (k.public_key_x().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__nistp256: Invalid public key X-coordonate size");
      return FALSE;
    }
    if (k.public_key_y().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__nistp256: Invalid public key Y-coordonate size");
      return FALSE;
    }
    if (k.public_key_compressed().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__nistp256: Invalid public compressed key size");
      return FALSE;
    }
garciay's avatar
garciay committed
    p__privateKey = OCTETSTRING(k.private_key().size(), k.private_key().data());
    p__publicKeyX = OCTETSTRING(k.public_key_x().size(), k.public_key_x().data());
    p__publicKeyY = OCTETSTRING(k.public_key_y().size(), k.public_key_y().data());
    p__publicKeyCompressed = OCTETSTRING(k.public_key_compressed().size(), k.public_key_compressed().data());
    p__compressedMode = INTEGER((int)k.public_key_compressed_mode());
    
garciay's avatar
garciay committed
    return TRUE;
  }

  /**
   * \brief    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
garciay's avatar
garciay committed
   *          This function should not be used by the ATS
   * \param   p_privateKey    The new private key value
   * \param   p_publicKeyX    The new public key value (x coordinate)
   * \param   p_publicKeyX    The new public key value (y coordinate)
   * \return  true on success, false otherwise
garciay's avatar
garciay committed
   fx_generateKeyPair_nistp256(out octetstring<UInt64> p_privateKey, out octetstring p_publicKeyX, out octetstring p_publicKeyY) return boolean;
  */
  BOOLEAN fx__generateKeyPair__brainpoolp256(
                                             OCTETSTRING& p__privateKey,
                                             OCTETSTRING& p__publicKeyX,
                                             OCTETSTRING& p__publicKeyY,
                                             OCTETSTRING& p__publicKeyCompressed,
                                             INTEGER& p__compressedMode
garciay's avatar
garciay committed
                                             ) {
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1);
garciay's avatar
garciay committed
    if (k.generate() != 0) {
      p__privateKey = OCTETSTRING();
      p__publicKeyX = OCTETSTRING();
      p__publicKeyY = OCTETSTRING();
      p__publicKeyCompressed = OCTETSTRING();
garciay's avatar
garciay committed
      return FALSE;
    }

garciay's avatar
garciay committed
    // Sanity checks
    if (k.private_key().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp256: Invalid private key size");
garciay's avatar
garciay committed
      return FALSE;
    }
    if (k.public_key_x().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp256: Invalid public key X-coordonate size");
garciay's avatar
garciay committed
      return FALSE;
    }
    if (k.public_key_y().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp256: Invalid public key Y-coordonate size");
      return FALSE;
    }
    if (k.public_key_compressed().size() != 32) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp256: Invalid public compressed key size");
garciay's avatar
garciay committed
      return FALSE;
    }
garciay's avatar
garciay committed
    p__privateKey = OCTETSTRING(k.private_key().size(), k.private_key().data());
    p__publicKeyX = OCTETSTRING(k.public_key_x().size(), k.public_key_x().data());
    p__publicKeyY = OCTETSTRING(k.public_key_y().size(), k.public_key_y().data());
    p__publicKeyCompressed = OCTETSTRING(k.public_key_compressed().size(), k.public_key_compressed().data());
    p__compressedMode = INTEGER((int)k.public_key_compressed_mode());
    
garciay's avatar
garciay committed
    return TRUE;
  }

  /**
   * \brief    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
garciay's avatar
garciay committed
   *          This function should not be used by the ATS
   * \param   p_privateKey    The new private key value
   * \param   p_publicKeyX    The new public key value (x coordinate)
   * \param   p_publicKeyX    The new public key value (y coordinate)
   * \return  true on success, false otherwise
garciay's avatar
garciay committed
   fx_generateKeyPair_nistp256(out octetstring<UInt64> p_privateKey, out octetstring p_publicKeyX, out octetstring p_publicKeyY) return boolean;
  */
  BOOLEAN fx__generateKeyPair__brainpoolp384(
                                             OCTETSTRING& p__privateKey,
                                             OCTETSTRING& p__publicKeyX,
                                             OCTETSTRING& p__publicKeyY,
                                             OCTETSTRING& p__publicKeyCompressed,
                                             INTEGER& p__compressedMode
garciay's avatar
garciay committed
                                             ) {
garciay's avatar
garciay committed
    security_ecc k(ec_elliptic_curves::brainpool_p_384_r1);
garciay's avatar
garciay committed
    if (k.generate() != 0) {
      p__privateKey = OCTETSTRING();
      p__publicKeyX = OCTETSTRING();
garciay's avatar
garciay committed
      p__publicKeyY = OCTETSTRING();
      p__publicKeyCompressed = OCTETSTRING();
garciay's avatar
garciay committed
      return FALSE;
    }

garciay's avatar
garciay committed
    // Sanity checks
    if (k.private_key().size() != 48) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp384: Invalid private key size");
garciay's avatar
garciay committed
      return FALSE;
    }
    if (k.public_key_x().size() != 48) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp384: Invalid public key X-coordonate size");
garciay's avatar
garciay committed
      return FALSE;
    }
    if (k.public_key_y().size() != 48) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp384: Invalid public key Y-coordonate size");
      return FALSE;
    }
    if (k.public_key_compressed().size() != 48) {
      loggers::get_instance().error("fx__generateKeyPair__brainpoolp384: Invalid public compressed key size");
garciay's avatar
garciay committed
      return FALSE;
    }
garciay's avatar
garciay committed
    p__privateKey = OCTETSTRING(k.private_key().size(), k.private_key().data());
    p__publicKeyX = OCTETSTRING(k.public_key_x().size(), k.public_key_x().data());
    p__publicKeyY = OCTETSTRING(k.public_key_y().size(), k.public_key_y().data());
    p__publicKeyCompressed = OCTETSTRING(k.public_key_compressed().size(), k.public_key_compressed().data());
    p__compressedMode = INTEGER((int)k.public_key_compressed_mode());

garciay's avatar
garciay committed
    return TRUE;
garciay's avatar
garciay committed

  //        group encryption

  //        group certificatesLoader

   * \brief    Load in memory cache the certificates available in the specified directory
   * \param   p_rootDirectory Root directory to access to the certificates identified by the certificate ID
   * \param   p_configId      A configuration identifier
garciay's avatar
garciay committed
   * @remark  This method SHALL be call before any usage of certificates
   * \return  true on success, false otherwise
garciay's avatar
garciay committed
   fx_loadCertificates(in charstring p_rootDirectory, in charstring p_configId) return boolean;
  */
  BOOLEAN fx__loadCertificates(
                               const CHARSTRING& p__rootDirectory,
                               const CHARSTRING& p__configId
                               ) {
    loggers::get_instance().log(">>> fx__loadCertificates: '%s', '%s'", static_cast<const char*>(p__rootDirectory), static_cast<const char*>(p__configId));

    std::string str(static_cast<const char*>(p__rootDirectory));
    if (p__configId.lengthof() != 0) {
      str += "/";
      str += std::string(static_cast<const char*>(p__configId));
    }
garciay's avatar
garciay committed
    params params;
    params.insert(std::pair<std::string, std::string>(std::string("sec_db_path"), str));
garciay's avatar
garciay committed
    if (security_services::get_instance().setup(params) == -1) {
      return FALSE;
    }
    
garciay's avatar
garciay committed
    return TRUE;
  }

  BOOLEAN fx__store__certificate(const CHARSTRING& p__cert__id, const OCTETSTRING& p__cert, const OCTETSTRING& p__private__key, const OCTETSTRING& p__public__key__x, const OCTETSTRING& p__public__key__y, const OCTETSTRING& p__public__key__compressed, const INTEGER& p__public__key__compressed__mode, const OCTETSTRING& p__hashid8, const OCTETSTRING& p__issuer, const OCTETSTRING_template& p__private__enc__key, const OCTETSTRING_template& p__public__enc__key__x, const OCTETSTRING_template& p__public__enc__key__y) {
    loggers::get_instance().log(">>> fx__store__certificate: '%s'", static_cast<const char*>(p__cert__id));

    int result;
    if (!p__private__enc__key.is_omit()) {
      const OCTETSTRING private_enc_key = p__private__enc__key.valueof();
      const OCTETSTRING public_enc_key_x = p__public__enc__key__x.valueof();
      const OCTETSTRING public_enc_key_y = p__public__enc__key__y.valueof();
      result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hashid8, p__issuer, private_enc_key, public_enc_key_x, public_enc_key_y);
      result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__public__key__compressed, p__public__key__compressed__mode, p__hashid8, p__issuer, OCTETSTRING(), OCTETSTRING(), OCTETSTRING());
    return (result == 0);
   * \brief    Unload from memory cache the certificates
   * \return  true on success, false otherwise
garciay's avatar
garciay committed
  BOOLEAN fx__unloadCertificates(
garciay's avatar
garciay committed
    return TRUE;
  }