Skip to content
LibItsSecurity_externals.cc 41.9 KiB
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
  /**
   * @desc    Produces a 256-bit (32-byte) hash value
   * @param   p_toBeHashedData Data to be used to calculate the hash value
   * @return  The hash value
   fx_hashWithSha256(in octetstring p_toBeHashedData) return Oct32;
  */
  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

  /**
   * @desc    Produces a 384-bit (48-byte) hash value
   * @param   p_toBeHashedData Data to be used to calculate the hash value
   * @return  The hash value
   fx_hashWithSha384(in octetstring p_toBeHashedData) return Oct48;
  */
  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
  /**
   * @desc    Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
garciay's avatar
garciay committed
   * @param   p_toBeSignedSecuredMessage    The data to be signed
   * @param   p_privateKey        The private key
   * @return  The signature value
   fx_signWithEcdsaNistp256WithSha256(in octetstring p_toBeSignedSecuredMessage, in octetstring<UInt64> p_privateKey) return octetstring;
  */
  OCTETSTRING fx__signWithEcdsaNistp256WithSha256(
                                                  const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                  const OCTETSTRING& p__privateKey
garciay's avatar
garciay committed
                                                  ) {
garciay's avatar
garciay committed
    // Calculate the SHA256 of the data
garciay's avatar
garciay committed
    sha256 hash;
    std::vector<unsigned char> hashData;
    // TODO Create SHX interface and add generate method with std::vector
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, hashData);
    // 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
  /**
   * @desc    Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
   * @param   p_toBeSignedSecuredMessage    The data to be signed
   * @param   p_privateKey        The private key
   * @return  The signature value
   fx_signWithEcdsaBrainpoolp256WithSha256(in octetstring p_toBeSignedSecuredMessage, in octetstring<UInt64> p_privateKey) return octetstring;
  */
  OCTETSTRING fx__signWithEcdsaBrainpoolp256WithSha256(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__privateKey
garciay's avatar
garciay committed
                                                       ) {
garciay's avatar
garciay committed
    // Calculate the SHA256 of the data
    sha256 hash;
    std::vector<unsigned char> hashData;
    // TODO Create SHX interface and add generate method with std::vector
    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, hashData);
    // 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();
  }

  /**
   * @desc    Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
   * @param   p_toBeSignedSecuredMessage    The data to be signed
   * @param   p_privateKey        The private key
   * @return  The signature value
   fx_signWithEcdsaBrainpoolp384WithSha384(in octetstring p_toBeSignedSecuredMessage, in octetstring<UInt64> p_privateKey) return octetstring;
  */
  OCTETSTRING fx__signWithEcdsaBrainpoolp384WithSha384(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__privateKey
garciay's avatar
garciay committed
                                                       ) {
garciay's avatar
garciay committed
    // Calculate the SHA384 of the data
    sha384 hash;
    std::vector<unsigned char> hashData;
    // TODO Create SHX interface and add generate method with std::vector
    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, hashData);
    // 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
  /**
   * @desc    Verify the signature of the specified data
   * @param   p_toBeVerifiedData          The data to be verified
   * @param   p_signature                 The signature
   * @param   p_ecdsaNistp256PublicKeyX   The public key (x coordinate)
   * @param   p_ecdsaNistp256PublicKeyY   The public key (y coordinate)
   * @return  true on success, false otherwise
   fx_verifyWithEcdsaNistp256WithSha256(in octetstring p_toBeVerifiedData, in octetstring p_signature, in octetstring p_ecdsaNistp256PublicKeyX, in octetstring p_ecdsaNistp256PublicKeyY) return boolean;
  */
  BOOLEAN fx__verifyWithEcdsaNistp256WithSha256(
                                                const OCTETSTRING& p__toBeVerifiedData,
                                                const OCTETSTRING& p__signature,
                                                const OCTETSTRING& p__ecdsaNistp256PublicKeyX,
                                                const OCTETSTRING& p__ecdsaNistp256PublicKeyY
                                                ) {
garciay's avatar
garciay committed
    // Calculate the hash
garciay's avatar
garciay committed
    sha256 hash;
    std::vector<unsigned char> hashData;
    // TODO Create SHX interface and add generate method with std::vector
garciay's avatar
garciay committed
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), static_cast<const unsigned char *>(p__toBeVerifiedData) + p__toBeVerifiedData.lengthof());
    hash.generate(tbh, hashData);
    // 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_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);
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
  /**
   * @desc    Verify the signature of the specified data
   * @param   p_toBeVerifiedData          The data to be verified
   * @param   p_signature                 The signature
   * @param   p_ecdsaBrainpoolp256PublicKeyX   The public key (x coordinate)
   * @param   p_ecdsaBrainpoolp256PublicKeyY   The public key (y coordinate)
   * @return  true on success, false otherwise
   fx_verifyWithEcdsaBrainpoolp256WithSha256(in octetstring p_toBeVerifiedData, in octetstring p_signature, in octetstring p_ecdsaBrainpoolp256PublicKeyX, in octetstring p_ecdsaBrainpoolp256PublicKeyY) return boolean;
  */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256(
                                                     const OCTETSTRING& p__toBeVerifiedData,
                                                     const OCTETSTRING& p__signature,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyX,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyY
garciay's avatar
garciay committed
                                                     ) {
garciay's avatar
garciay committed
    // Calculate the hash
    sha256 hash;
    std::vector<unsigned char> hashData;
    // TODO Create SHX interface and add generate method with std::vector
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), static_cast<const unsigned char *>(p__toBeVerifiedData) + p__toBeVerifiedData.lengthof());
    hash.generate(tbh, hashData);
    // 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_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;
  }

  /**
   * @desc    Verify the signature of the specified data
   * @param   p_toBeVerifiedData          The data to be verified
   * @param   p_signature                 The signature
   * @param   p_ecdsaBrainpoolp384PublicKeyX   The public key (x coordinate)
   * @param   p_ecdsaBrainpoolp384PublicKeyY   The public key (y coordinate)
   * @return  true on success, false otherwise
   fx_verifyWithEcdsaBrainpoolp384WithSha384(in octetstring p_toBeVerifiedData, in octetstring p_signature, in octetstring p_ecdsaBrainpoolp384PublicKeyX, in octetstring p_ecdsaBrainpoolp384PublicKeyY) return boolean;
  */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384(
                                                     const OCTETSTRING& p__toBeVerifiedData,
                                                     const OCTETSTRING& p__signature,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyX,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyY
garciay's avatar
garciay committed
                                                     ) {
garciay's avatar
garciay committed
    // Calculate the hash
    sha384 hash;
    std::vector<unsigned char> hashData;
    // TODO Create SHX interface and add generate method with std::vector
    std::vector<unsigned char> tbh(static_cast<const unsigned char *>(p__toBeVerifiedData), static_cast<const unsigned char *>(p__toBeVerifiedData) + p__toBeVerifiedData.lengthof());
    hash.generate(tbh, hashData);
    // 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_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;
  }
  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;
  }

  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;
  }
  
  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;
  }
  
  OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__peerPublicKeyX, const OCTETSTRING& p__peerPublicKeyY, OCTETSTRING& p__publicEncKeyX, OCTETSTRING& p__publicEncKeyY, 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__peerPublicKeyX: ", p__peerPublicKeyX);
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__peerPublicKeyY: ", p__peerPublicKeyY);
    
    // 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> peer_public_key_x(static_cast<const unsigned char *>(p__peerPublicKeyX), p__peerPublicKeyX.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyX));
    std::vector<unsigned char> peer_public_key_y(static_cast<const unsigned char *>(p__peerPublicKeyY), p__peerPublicKeyY.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyY));
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, peer_public_key_x, peer_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__publicEncKeyX = OCTETSTRING(ec.public_key_x().size(), ec.public_key_x().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key X: ", p__publicEncKeyX);
    p__publicEncKeyY = OCTETSTRING(ec.public_key_y().size(), ec.public_key_y().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key Y: ", p__publicEncKeyY);
    // 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);
    
  OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__publicKeyX, const OCTETSTRING& p__publicKeyY, const OCTETSTRING& p__nonce, const OCTETSTRING& p__authentication_vector) {
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage);
    // 1. Create security_ecc instance based of private encryption key, recipient's public ephemeral keys will be required

    // 2. Generate the shared secret value based on recipient's public ephemeral keys will be required

    
    return OCTETSTRING();
  }
garciay's avatar
garciay committed
  /**
   * @desc    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
   *          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
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();
      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;
    }
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());
    return TRUE;
  }

  /**
   * @desc    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
   *          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
   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
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();
      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;
    }
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());
    return TRUE;
  }

  /**
   * @desc    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
   *          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
   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
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();
      return FALSE;
    }

garciay's avatar
garciay committed
    // Sanity checks
    if (k.private_key().size() != 48) {
      loggers::get_instance().error("fx__generateKeyPair__nistp256: Invalid private key size");
      return FALSE;
    }
    if (k.public_key_x().size() != 48) {
      loggers::get_instance().error("fx__generateKeyPair__nistp256: Invalid public key X-coordonate size");
      return FALSE;
    }
    if (k.public_key_y().size() != 48) {
      loggers::get_instance().error("fx__generateKeyPair__nistp256: Invalid public key Y-coordonate 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());
    return TRUE;
garciay's avatar
garciay committed

  //        group encryption

  //        group certificatesLoader

garciay's avatar
garciay committed
   * @desc    Load in memory cache the certificates available in the specified directory
garciay's avatar
garciay committed
   * @param   p_rootDirectory Root directory to access to the certificates identified by the certificate ID
   * @param   p_configId      A configuration identifier
   * @remark  This method SHALL be call before any usage of certificates
   * @return  true on success, false otherwise
   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__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__hashid8, p__issuer, private_enc_key, public_enc_key_x, public_enc_key_y);
    } else {
      result = security_services::get_instance().store_certificate(p__cert__id, p__cert, p__private__key, p__public__key__x, p__public__key__y, p__hashid8, p__issuer, OCTETSTRING(), OCTETSTRING(), OCTETSTRING());
    return (result == 0);
garciay's avatar
garciay committed
   * @desc    Unload from memory cache the certificates
garciay's avatar
garciay committed
   * @return  true on success, false otherwise
garciay's avatar
garciay committed
  BOOLEAN fx__unloadCertificates(
garciay's avatar
garciay committed
    return TRUE;
  }

  /**
   * @desc    Read the specified certificate
garciay's avatar
garciay committed
   * @param   p_certificateId the certificate identifier
   * @param   p_certificate   the expected certificate
   * @return  true on success, false otherwise
garciay's avatar
garciay committed
  BOOLEAN fx__readCertificate(
                              const CHARSTRING& p__certificateId,
                              OCTETSTRING& p__certificate
                              ) {
    loggers::get_instance().log(">>> fx__readCertificate: '%s'", static_cast<const char*>(p__certificateId));

    if (security_services::get_instance().read_certificate(p__certificateId, p__certificate) == -1) {
      return FALSE;
    }
    
garciay's avatar
garciay committed
    return TRUE;
  }

  BOOLEAN fx__readCertificateFromDigest(
                                        const OCTETSTRING& p__digest,
                                        CHARSTRING& p__certificateId) {
    loggers::get_instance().log_msg(">>> fx__readCertificateFromDigest: ", p__digest);
garciay's avatar
garciay committed

    if (security_services::get_instance().read_certificate_from_digest(p__digest, p__certificateId) == -1) {
      return FALSE;
    }
    loggers::get_instance().log_msg("fx__readCertificateFromDigest: ", p__certificateId);
    
    return TRUE;
  }
  
  /**
   * @desc    Read the specified certificate digest
garciay's avatar
garciay committed
   * @param   p_certificateId the certificate identifier
   * @param   p_digest   the expected certificate
   * @return  true on success, false otherwise
garciay's avatar
garciay committed
  BOOLEAN fx__readCertificateDigest(
                                    const CHARSTRING& p__certificateId,
                                    OCTETSTRING& p__digest
                                    ) {
    loggers::get_instance().log(">>> fx__readCertificateDigest: '%s'", static_cast<const char*>(p__certificateId));

    if (security_services::get_instance().read_certificate_digest(p__certificateId, p__digest) == -1) {
      return FALSE;
    }
    
garciay's avatar
garciay committed
    return TRUE;
  }

  /**
   * @desc    Read the private keys for the specified certificate
   * @param   p_certificateId     the keys identifier
garciay's avatar
garciay committed
   * @param   p_signingPrivateKey the signing private key
   * @return  true on success, false otherwise
garciay's avatar
garciay committed
  BOOLEAN fx__readSigningKey(
                             const CHARSTRING& p__certificateId,
garciay's avatar
garciay committed
                             OCTETSTRING& p__signingPrivateKey
                             ) {
    loggers::get_instance().log(">>> fx__readSigningKey: '%s'", static_cast<const char*>(p__certificateId));

    if (security_services::get_instance().read_private_key(p__certificateId, p__signingPrivateKey) == -1) {
      return FALSE;
    }
    
garciay's avatar
garciay committed
    return TRUE;
  }

  /**
   * @desc    Read the private keys for the specified certificate
garciay's avatar
garciay committed
   * @param   p_keysId            the keys identifier
   * @param   p_encryptPrivateKey the encrypt private key
   * @return  true on success, false otherwise
   fx_readEncryptingKey(in charstring p_keysId, out Oct32 p_encryptingPrivateKey) return boolean;
  */
  BOOLEAN fx__readEncryptingKey(
                                const CHARSTRING& p__certificateId,
garciay's avatar
garciay committed
                                OCTETSTRING& p__encryptingPrivateKey
                                ) {
    loggers::get_instance().log(">>> fx__readSigningKey: '%s'", static_cast<const char*>(p__certificateId));

    if (security_services::get_instance().read_private_enc_key(p__certificateId, p__encryptingPrivateKey) == -1) {
      return FALSE;
    }

garciay's avatar
garciay committed
    return TRUE;
  }

  //        group geodesic 

  /*          * @desc    Check that given polygon doesn't have neither self-intersections nor holes.
   * @param   p_region   Polygonal Region
   * @return  true on success, false otherwise
   * @verdict Unchanged
   fx_isValidPolygonalRegion(in PolygonalRegion p_region) return boolean;
  */
  BOOLEAN fx__isValidPolygonalRegion(
                                     const IEEE1609dot2BaseTypes::PolygonalRegion& p__region
                                     ) {
    return TRUE;
  }

  /*          * @desc Check if a polygonal region is inside another one
   * @param p_parent  The main polygonal region
   * @param p_region  The polygonal region to be included
   * @return true on success, false otherwise
   * @verdict Unchanged
   fx_isPolygonalRegionInside(in PolygonalRegion p_parent, in PolygonalRegion p_region) return boolean;
  */
  BOOLEAN fx__isPolygonalRegionInside(
                                      const IEEE1609dot2BaseTypes::PolygonalRegion& p__parent,
                                      const IEEE1609dot2BaseTypes::PolygonalRegion& p__region
                                      ) {
    return TRUE;
  }

  /*          * @desc Check that the location is inside a circular region
   * @param p_region      The circular region to consider
   * @param p_location    The device location
   * @return true on success, false otherwise
   * @verdict Unchanged
   fx_isLocationInsideCircularRegion(in CircularRegion p_region, in ThreeDLocation p_location) return boolean;
  */
  BOOLEAN fx__isLocationInsideCircularRegion(
                                             const IEEE1609dot2BaseTypes::CircularRegion& p__region,
                                             const IEEE1609dot2BaseTypes::ThreeDLocation& p__location
                                             ) {
    return TRUE;
  }

  /*          * @desc Check that the location is inside a rectangular region
   * @param p_region      The rectangular region to consider
   * @param p_location    The device location
   * @return true on success, false otherwise
   * @verdict Unchanged
   fx_isLocationInsideRectangularRegion(in SequenceOfRectangularRegion p_region, in ThreeDLocation p_location) return boolean;
  */
  BOOLEAN fx__isLocationInsideRectangularRegion(
                                                const IEEE1609dot2BaseTypes::SequenceOfRectangularRegion& p__region,
                                                const IEEE1609dot2BaseTypes::ThreeDLocation& p__location
                                                ) {
    return TRUE;
  }

  /*          * @desc Check that the location is inside a polygonal region
   * @param p_region      The polygonal region to consider
   * @param p_location    The device location
   * @return true on success, false otherwise
   * @verdict Unchanged
   fx_isLocationInsidePolygonalRegion(in PolygonalRegion p_region, in ThreeDLocation p_location) return boolean;
  */
  BOOLEAN fx__isLocationInsidePolygonalRegion(
                                              const IEEE1609dot2BaseTypes::PolygonalRegion& p__region,
                                              const IEEE1609dot2BaseTypes::ThreeDLocation& p__location
                                              ) {
    return TRUE;
  }


  /*          * @desc Check if the location is inside an identified region
   * @param p_region      The identified region to consider
   * @param p_location    The device location
   * @return true on success, false otherwise
   * @verdict Unchanged
   fx_isLocationInsideIdentifiedRegion(in IdentifiedRegion p_region, in ThreeDLocation p_location) return boolean;
  */
  BOOLEAN fx__isLocationInsideIdentifiedRegion(
                                               const IEEE1609dot2BaseTypes::IdentifiedRegion& p__region,
                                               const IEEE1609dot2BaseTypes::ThreeDLocation& p__location
                                               ) {
    return TRUE;
  }

  /*          * @desc Check if the location is inside an undefined region
   * @param p_region      The identified region to consider
   * @param p_location    The device location
   * @return true on success, false otherwise
   * @verdict Unchanged
   fx_isLocationInsideOtherRegion(in octetstring p_region, in ThreeDLocation p_location) return boolean; 
  */
  BOOLEAN fx__isLocationInsideOtherRegion(
                                          const OCTETSTRING& p_region,
                                          const IEEE1609dot2BaseTypes::ThreeDLocation& p_location
                                          ) {
    return TRUE;
  } 

  /*           * @desc    Check that p_circular_region_1 circular region is included into p_circular_region_2 circular region
   * @param   p_circular_region_1    Circular region 1
   * @param   p_circular_region_2    Circular region 2
   * @return  true on success, false otherwise
   fx_areCirclesInside(in CircularRegion p_circular_region_1, in CircularRegion p_circular_region_2) return boolean;
  */
  BOOLEAN fx__areCirclesInside(
                               const IEEE1609dot2BaseTypes::CircularRegion& p_circular_region_1,
                               const IEEE1609dot2BaseTypes::CircularRegion& p_circular_region_2
                               ) {
    return TRUE;
  }

  /*           * @desc    Check that p_rectanglar_region_1 rectangular region is included into p_rectanglar_region_2 rectangular region
   * @param   p_rectanglar_region_1    Rectangular region 1
   * @param   p_rectanglar_region_2    Rectangular region 2
   * @return  true on success, false otherwise
   fx_areRectanglesInside(in SequenceOfRectangularRegion p_rectanglar_region_1, in SequenceOfRectangularRegion p_rectanglar_region_2) return boolean;
  */
  BOOLEAN fx__areRectanglesInside(
                                  const IEEE1609dot2BaseTypes::SequenceOfRectangularRegion& p_rectanglar_region_1,
                                  const IEEE1609dot2BaseTypes::SequenceOfRectangularRegion& p_rectanglar_region_2
                                  ) {
    return TRUE;
  }

  /*           * @desc    Check that p_polygonal_region_1 polygonal region is included into p_polygonal_region_2 polygonal region
   * @param   p_polygonal_region_1    Polygonal region 1
   * @param   p_polygonal_region_2    Polygonal region 2
   * @return  true on success, false otherwise
   fx_arePolygonsInside(in PolygonalRegion p_polygonal_region_1, in PolygonalRegion p_polygonal_region_2) return boolean;
  */
  BOOLEAN fx__arePolygonsInside(
                                const IEEE1609dot2BaseTypes::PolygonalRegion& p_polygonal_region_1,
                                const IEEE1609dot2BaseTypes::PolygonalRegion& p_polygonal_region_2
                                ) {
    return TRUE;
  }

  /*          * @desc Convert a spacial coordinate from DMS to Dms
   * @param p_degrees The degrees (D)
   * @param p_minutes The minutes (M)
   * @param p_seconds The seconds (S)
   * @param p_latlon  The latitude/longitude: (N|S|E|W)
   * @return The decimal coordinate on success, 0.0, otherwise
   * @verdict Unchanged
   fx_dms2dd(in Int p_degrees, in Int p_minutes, in float p_seconds, in Oct1 p_latlon) return float;
  */
  FLOAT fx__dms2dd(
                   const INTEGER& p__degrees,
                   const INTEGER& p__minutes,
                   const FLOAT& p__seconds,
                   const OCTETSTRING& p__latlon
                   ) {
    return 0.0;
  }

} // end of namespace