Commit f595d03c authored by garciay's avatar garciay
Browse files

STF545: Validate ECIES implementation

parent be8bc373
Loading
Loading
Loading
Loading
+47 −17
Original line number Diff line number Diff line
@@ -314,10 +314,10 @@ namespace LibItsSecurity__Functions
    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) {
  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) {
    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);
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__recipientsPublicKeyX: ", p__recipientsPublicKeyX);
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__recipientsPublicKeyY: ", p__recipientsPublicKeyY);
    
    // 1. Generate new Private/Public key
    security_ecc ec(ec_elliptic_curves::nist_p_256);
@@ -326,8 +326,8 @@ namespace LibItsSecurity__Functions
      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));
    std::vector<unsigned char> peer_public_key_x(static_cast<const unsigned char *>(p__recipientsPublicKeyX), p__recipientsPublicKeyX.lengthof() + static_cast<const unsigned char *>(p__recipientsPublicKeyX));
    std::vector<unsigned char> peer_public_key_y(static_cast<const unsigned char *>(p__recipientsPublicKeyY), p__recipientsPublicKeyY.lengthof() + static_cast<const unsigned char *>(p__recipientsPublicKeyY));
    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();
@@ -336,13 +336,13 @@ namespace LibItsSecurity__Functions
    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);
    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);
    p__publicEphemeralKeyX = OCTETSTRING(ec.public_key_x().size(), ec.public_key_x().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key X: ", p__publicEphemeralKeyX);
    p__publicEphemeralKeyY = OCTETSTRING(ec.public_key_y().size(), ec.public_key_y().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key Y: ", p__publicEphemeralKeyY);
    // 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);
@@ -362,17 +362,47 @@ namespace LibItsSecurity__Functions
    return 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) {
  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) {
    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__publicEphemeralKeyX: ", p__publicEphemeralKeyX);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__publicEphemeralKeyY: ", p__publicEphemeralKeyY);
    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 based of private encryption key, recipient's public ephemeral keys will be required
    // 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);
    
    // 2. Generate the shared secret value based on recipient's public ephemeral keys will be required
    std::vector<unsigned char> ephemeral_public_key_x(static_cast<const unsigned char*>(p__publicEphemeralKeyX), p__publicEphemeralKeyX.lengthof() + static_cast<const unsigned char*>(p__publicEphemeralKeyX));
    std::vector<unsigned char> ephemeral_public_key_y(static_cast<const unsigned char*>(p__publicEphemeralKeyY), p__publicEphemeralKeyY.lengthof() + static_cast<const unsigned char*>(p__publicEphemeralKeyY));
    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, ephemeral_public_key_x, ephemeral_public_key_y, enc_sym_key, nonce, authentication_vector) == -1) {
      loggers::get_instance().warning("fx__decryptWithEciesNistp256WithSha256: 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__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;
  }
  
  /**
   * @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
+86 −9
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
    return -1;
  }
  if ((_pub_key_x.size() == 0) || (_pub_key_y.size() == 0)) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key format: Keys shall be generated");
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Keys shall be generated");
    return -1;
  }
  _encryption_algotithm = p_enc_algorithm;
@@ -199,7 +199,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  // Generate the shared secret key
  int result = ::ECDH_compute_key(_secret_key.data(), _secret_key.size(), ec_point, _ec_key, NULL);
  if (result == -1) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key format: Failed to generate shared secret key");
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to generate shared secret key");
    ::EC_POINT_free(ec_point);
    return -1;
  }
@@ -213,7 +213,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  std::vector<unsigned char> digest(k_enc.size() + k_mac.size(), 0x00);
  loggers::get_instance().log("security_ecc::generate_and_derive_ephemeral_key: k_enc size:%d - k_mac size: %d - digest size:%d: ", k_enc.size(), k_mac.size(), digest.size());
  if (PKCS5_PBKDF2_HMAC((const char*)_secret_key.data(), _secret_key.size(), NULL, 0, 2000, EVP_sha256(), digest.size(), digest.data()) != 1) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key format: Failed to derive shared secret key");
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to derive shared secret key");
    return -1;
  }
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: digest: ", digest.data(), digest.size());
@@ -235,7 +235,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p

  // Encrypt the _sym_key
  if (encrypt(encryption_algotithm::aes_128_ccm, _sym_key, _nonce, _sym_key, _enc_sym_key) == -1) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key format: Failed to encrypt key");
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to encrypt key");
    return -1;
  }
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: Encrypted symmetric key: ", encrypted_symmetric_key().data(), encrypted_symmetric_key().size());
@@ -243,6 +243,80 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  return 0;
}

int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_private_enc_key, const std::vector<unsigned char>& p_ephemeral_public_key_x, const std::vector<unsigned char>& p_ephemeral_public_key_y, const std::vector<unsigned char>& p_enc_sym_key, const std::vector<unsigned char>& p_expected_nonce, const std::vector<unsigned char>& p_authentication_vector) {
  loggers::get_instance().log(">>> security_ecc::generate_and_derive_ephemeral_key");

  // Sanity checks
  if (_pri_key.size() == 0) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Key shall be generated");
    return -1;
  }
  _encryption_algotithm = p_enc_algorithm;
  _nonce = p_expected_nonce;
  _enc_sym_key = p_enc_sym_key;
  _tag = p_authentication_vector;

  // Set buffers size
  int len = (EC_GROUP_get_degree(_ec_group) + 7) / 8;
  _secret_key.resize(len);
  
  // Convert the peer public encryption key to an EC point
  EC_POINT *ec_point = nullptr;
  bin_to_ec_point(p_ephemeral_public_key_x, p_ephemeral_public_key_y, &ec_point);
  // Generate the shared symmetric key
  int result = ::ECDH_compute_key(_secret_key.data(), _secret_key.size(), ec_point, _ec_key, NULL);
  if (result == -1) {
    ::EC_POINT_free(ec_point);
    return -1;
  }
  ::EC_POINT_free(ec_point);
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: _secret_key: ", _secret_key.data(), _secret_key.size());
  
  // Derive the shared secret key
  std::vector<unsigned char> k_enc(12 + 16 + 16, 0x00); // Nonce + AES 128 CCM key + Tag
                                                        // TODO Use ec_encryption_algorithm
  std::vector<unsigned char> k_mac(32 + 32, 0x00);
  std::vector<unsigned char> digest(k_enc.size() + k_mac.size(), 0x00);
  loggers::get_instance().log("security_ecc::generate_and_derive_ephemeral_key: k_enc size:%d - k_mac size: %d - digest size:%d: ", k_enc.size(), k_mac.size(), digest.size());
  if (PKCS5_PBKDF2_HMAC((const char*)_secret_key.data(), _secret_key.size(), NULL, 0, 2000, EVP_sha256(), digest.size(), digest.data()) != 1) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to derive shared secret key");
    return -1;
  }
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: digest: ", digest.data(), digest.size());

  // Extract AES 128 parameters
  std::vector<unsigned char> nonce(12, 0x00); // TODO Use ec_encryption_algorithm
  std::copy(digest.begin(), digest.begin() + nonce.size(), nonce.begin());
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: Generated nonce: ", nonce.data(), nonce.size());
  std::vector<unsigned char> sym_key(16, 0x00);
  std::copy(digest.begin() + nonce.size(), digest.begin() + nonce.size() + sym_key.size(), sym_key.begin());
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: sym_key: ", sym_key.data(), sym_key.size());
  std::vector<unsigned char> tag(16, 0x00);
  std::copy(digest.begin() + nonce.size() + sym_key.size(), digest.begin() + nonce.size() + sym_key.size() + tag.size(), tag.begin()); // TODO Useless???
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: tag: ", tag.data(), tag.size());

  if (_nonce != nonce) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to derive nonce vector");
    return -1;
  }
  
  // Extract the HMAC key
  std::vector<unsigned char> hmac_secret(32 + 32, 0x00);
  std::copy(digest.data() + 44, digest.data() + 44 + 32 + 32, hmac_secret.begin());
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: hmac_secret: ", hmac_secret.data(), hmac_secret.size());

  // Decrypt the symmetric key
  std::vector<unsigned char> skey;
  if (decrypt(p_enc_algorithm, sym_key, nonce, p_authentication_vector, p_enc_sym_key, skey) == -1) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Failed to decrypt key");
    return -1;
  }
  _sym_key = skey;
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: Decrypted symmetric key: ", symmetric_encryption_key().data(), symmetric_encryption_key().size());
  
  return 0;
}

int security_ecc::encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message) {
  loggers::get_instance().log(">>> security_ecc::encrypt: %d", p_enc_algorithm);

@@ -351,7 +425,7 @@ int security_ecc::encrypt(const encryption_algotithm p_enc_algorithm, const std:
}

int security_ecc::decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message) {
  loggers::get_instance().log(">>> security_ecc::decrypt");
  loggers::get_instance().log(">>> security_ecc::decrypt: %d", p_enc_algorithm);

  _encryption_algotithm = p_enc_algorithm;
  _sym_key = p_key;
@@ -384,20 +458,21 @@ int security_ecc::decrypt(const encryption_algotithm p_enc_algorithm, const std:
  p_message.resize(p_enc_message.size());
  int len = 0;
  int result = EVP_DecryptUpdate(ctx, p_message.data(), &len, p_enc_message.data(), p_enc_message.size());
  loggers::get_instance().log("security_ecc::decrypt: len: %d", len);
  loggers::get_instance().log("security_ecc::decrypt: result: %d", result);
  ::EVP_CIPHER_CTX_free(ctx);
  
  return (result > 0) ? 0 : -1;
}

int security_ecc::decrypt(const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message) {
  loggers::get_instance().log(">>> security_ecc::decrypt");
int security_ecc::decrypt(const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message) {
  loggers::get_instance().log(">>> security_ecc::decrypt: %d", _encryption_algotithm);

  // Sanity checks
  if ((_pri_key.size() == 0) || (_secret_key.size() == 0)) {
    loggers::get_instance().warning("security_ecc::decrypt: Constrictor format #2 shall be used");
    return -1;
  }
  _nonce = p_nonce;
  _tag = p_tag;
  
  // Initialize the context and decryption operation
@@ -421,11 +496,13 @@ int security_ecc::decrypt(const std::vector<unsigned char>& p_nonce, const std::
  // Set expected tag value
  EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, _tag.size(), _tag.data());
  // Specify key and IV
  EVP_DecryptInit_ex(ctx, NULL, NULL, _secret_key.data(), _nonce.data());
  EVP_DecryptInit_ex(ctx, NULL, NULL, _sym_key.data(), _nonce.data());
  // Decrypt plaintext, verify tag: can only be called once
  p_message.resize(p_enc_message.size());
  int len = 0;
  int result = EVP_DecryptUpdate(ctx, p_message.data(), &len, p_enc_message.data(), p_enc_message.size());
  loggers::get_instance().log("security_ecc::decrypt: len: %d", len);
  loggers::get_instance().log("security_ecc::decrypt: result: %d", result);
  ::EVP_CIPHER_CTX_free(ctx);
  
  return (result > 0) ? 0 : -1;
+20 −14
Original line number Diff line number Diff line
@@ -124,20 +124,17 @@ public: //! \publicsection
  int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_recipients_public_key_x, const std::vector<unsigned char>& p_recipients_public_key_y);

    /*!
   * \fn int generate_and_derive_ephemeral_key(const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y);
   * \fn int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_private_enc_key, const std::vector<unsigned char>& p_ephemeral_public_key_x, const std::vector<unsigned char>& p_ephemeral_public_key_y);
   * \brief Generate a shared secret key and derive it using KDF2 algorithm.
   * \param[in] p_enc_algorithm The encryption algorithm to be used 
   * \param[in] p_enc_key The private encryption key associated to the public encryption key
   * \param[in] p_peer_public_key_x The recipient public key X-coordinate
   * \param[in] p_peer_public_key_x The recipient public key Y-coordinate
   * \param[in] p_private_enc_key The private encryption key associated to the public encryption key
   * \param[in] p_ephemeral_public_key_x The recipient public key X-coordinate
   * \param[in] p_ephemeral_public_key_x The recipient public key Y-coordinate
   * \remark To get the secret key, uses \see secret_key method
   * \remark To get the generated symmetric encryption key, uses \see symmetric_encryption_key method
   * \remark To get the generated nonce vector, uses \see nonce method
   * \remark To get the decrypteded symmetric encryption key, uses \see symmetric_encryption_key method
   * \return 0 on success, -1 otherwise
   */
  int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_private_enc_key, const std::vector<unsigned char>& p_recipients_public_key_x, const std::vector<unsigned char>& p_recipients_public_key_y) { return -1; };


  int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_private_enc_key, const std::vector<unsigned char>& p_ephemeral_public_key_x, const std::vector<unsigned char>& p_ephemeral_public_key_y, const std::vector<unsigned char>& p_enc_sym_key, const std::vector<unsigned char>& p_expected_nonce, const std::vector<unsigned char>& p_authentication_vector);

  /*!
   * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message);
@@ -167,7 +164,7 @@ public: //! \publicsection
  int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message);
  /*!
   * \fn int decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message);
   * \brief Decryption using the specified algorithm.
   * \brief Decryption using the specified parameters.
   * \param[in] p_enc_algorithm The algorithm to use for the decryption
   * \param[in] p_nonce The algorithm to use for the encryption
   * \param[in] p_tag The algorithm to use for the encryption
@@ -179,9 +176,18 @@ public: //! \publicsection
   * \return 0 on success, -1 otherwise
   */
  int decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message);
  
  // TODO To be reorganised
  int decrypt(const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message);
  /*!
   * \fn int decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message);
   * \brief Decryption using default parameters.
   * \param[in] p_tag The algorithm to use for the encryption
   * \param[in] p_enc_message The message to be decrypted
   * \param[out] p_message The decrypted message
   * \remark To get the generated symmetric encryption key, uses \see symmetric_encryption_key method
   * \remark To get the generated nonce vector, uses \see nonce method
   * \remark To get the generated tag, uses \see tag method
   * \return 0 on success, -1 otherwise
   */
  int decrypt(const std::vector<unsigned char>& p_tag, const std::vector<unsigned char>& p_enc_message, std::vector<unsigned char>& p_message);
  
  inline const std::vector<unsigned char>& private_key() const { return _pri_key; };
  inline const std::vector<unsigned char>& public_key_x() const { return _pub_key_x; };