Commit 8071a2d8 authored by garciay's avatar garciay
Browse files

STF545: Start ECIES implementation

parent 04d4a68d
Loading
Loading
Loading
Loading
+17 −12
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ 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__hmac, OCTETSTRING& p__authentication_vector, OCTETSTRING& p__nonce) {
  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);
@@ -328,13 +328,21 @@ namespace LibItsSecurity__Functions
    // 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> authentication_vector; // FIXME Check what to do with the authentication_vector
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, peer_public_key_x, peer_public_key_y, authentication_vector) == -1) {
    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();
    }
    p__authentication_vector = OCTETSTRING(authentication_vector.size(), authentication_vector.data());
    // 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);
@@ -351,20 +359,17 @@ namespace LibItsSecurity__Functions
    OCTETSTRING os(enc_message.size(), enc_message.data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc message||Tag: ", os);
    
    // 5. Setup the output parameters
    p__hmac = OCTETSTRING(ec.enc_hmac().size(), ec.enc_hmac().data());
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Hmac: ", p__hmac);
    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);
    
    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) {
    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();
  }
  
+7 −18
Original line number Diff line number Diff line
@@ -175,7 +175,7 @@ int security_ecc::generate() {
  return 0;
}

int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector) {
int security_ecc::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) {
  loggers::get_instance().log(">>> security_ecc::generate_and_derive_ephemeral_key");

  // Sanity checks
@@ -192,9 +192,10 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  // 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_peer_public_enc_key_x, p_peer_public_enc_key_y, &ec_point);
  bin_to_ec_point(p_recipients_public_key_x, p_recipients_public_key_y, &ec_point);
  // Generate the shared secret key
  int result = ::ECDH_compute_key(_secret_key.data(), _secret_key.size(), ec_point, _ec_key, NULL);
  if (result == -1) {
@@ -205,17 +206,13 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  ::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());
  
  // Create the ECIES tag
  p_authentication_vector.resize(16); // Use ec_encryption_algorithm
  ::RAND_pseudo_bytes(p_authentication_vector.data(), p_authentication_vector.size());
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: authentication vector: ", p_authentication_vector.data(), p_authentication_vector.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(), p_authentication_vector.data(), p_authentication_vector.size(), 1000, EVP_sha256(), digest.size(), digest.data()) != 1) {
  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");
    return -1;
  }
@@ -229,7 +226,7 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  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());
  _tag.resize(16);
  std::copy(digest.begin() + _nonce.size() + _sym_key.size(), digest.begin() + _nonce.size() + _sym_key.size() + _tag.size(), _tag.begin());
  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());
  // Extract the HMAC key
  std::vector<unsigned char> hmac_secret(32 + 32, 0x00);
@@ -237,19 +234,11 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: hmac_secret: ", hmac_secret.data(), hmac_secret.size());

  // Encrypt the _sym_key
  std::vector<unsigned char> encrypted_sym_key;
  if (encrypt(encryption_algotithm::aes_128_ccm, _sym_key, _nonce, _sym_key, encrypted_sym_key) == -1) {
  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");
    return -1;
  }
  
  // Generate the HMAC
  // FIXME Seems to be unused
  hmac h(hash_algorithms::sha_256); // TODO Use ec_encryption_algorithm
  if (h.generate(encrypted_sym_key, hmac_secret, _hmac) == -1) {
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key format: Failed to generate HMAC");
    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());
  
  return 0;
}
+7 −7
Original line number Diff line number Diff line
@@ -50,10 +50,10 @@ class security_ecc {
  std::vector<unsigned char> _pub_key_x;      /*!< Public key X-coordinate storage */
  std::vector<unsigned char> _pub_key_y;      /*!< Public key Y-coordinate storage */
  std::vector<unsigned char> _secret_key;     /*!< Shared secret key generated by ECIES encryption method */
  std::vector<unsigned char> _hmac;           /*!< HMAC key resulting of the derivation of the shared secret key */
  std::vector<unsigned char> _enc_key_x;      /*!< Ephemeral public key X-coordinate storage */
  std::vector<unsigned char> _enc_key_y;      /*!< Ephemeral public key Y-coordinate storage */
  std::vector<unsigned char> _sym_key;        /*!< AES symmetric encryption key generated by encryption method */
  std::vector<unsigned char> _enc_sym_key;    /*!< Encrypted AES symmetric encryption key generated by encryption method */
  std::vector<unsigned char> _nonce;          /*!< Initial Vector generated by encryption method */
  std::vector<unsigned char> _tag;            /*!< Tag vector generated by encryption method */
  
@@ -109,19 +109,19 @@ public: //! \publicsection
  int sign_verif(const std::vector<unsigned char>& p_data, const std::vector<unsigned char>& p_signature);
  
  /*!
   * \fn int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector);
   * \fn 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);
   * \brief Generate a shared secret key and derive it using KDF2 algorithm.
   *        This method shall be used by the sender. Fresh keys will be genrated for each cyphering operation
   * \param[in] p_enc_algorithm The encryption algorithm to be used 
   * \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_recipients_public_key_x The recipient public key X-coordinate
   * \param[in] p_recipients_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
   * \see encrypt methog to encrypt a message based of the generated symetric encryption key
   * \return 0 on success, -1 otherwise
   */
  int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector);
  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);
@@ -135,7 +135,7 @@ public: //! \publicsection
   * \remark To get the generated nonce vector, uses \see nonce 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_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector) { 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_recipients_public_key_x, const std::vector<unsigned char>& p_recipients_public_key_y) { return -1; };



@@ -189,7 +189,7 @@ public: //! \publicsection
  inline const std::vector<unsigned char>& secret_key() const { return _secret_key; };
  inline const std::vector<unsigned char>& encryption_key_x() const { return _enc_key_x; };
  inline const std::vector<unsigned char>& encryption_key_y() const { return _enc_key_y; };
  inline const std::vector<unsigned char>& enc_hmac() const { return _hmac; };
  inline const std::vector<unsigned char>& encrypted_symmetric_key() const { return _enc_sym_key; };
  inline const std::vector<unsigned char>& symmetric_encryption_key() const { return _sym_key; };
  inline const std::vector<unsigned char>& nonce() const { return _nonce; };
  inline const std::vector<unsigned char>& tag() const { return _tag; };