Commit 733ce250 authored by garciay's avatar garciay
Browse files

STF545: Validate ECIES implementation

parent f595d03c
Loading
Loading
Loading
Loading
+49 −17
Original line number Diff line number Diff line
@@ -192,6 +192,23 @@ 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);
  unsigned int nonce_length;
  unsigned int sym_key_length;
  unsigned int tag_length;
  unsigned int k_length;
  switch (_encryption_algotithm) {
  case encryption_algotithm::aes_128_ccm:
    // No break;
  case encryption_algotithm::aes_128_gcm:
    nonce_length = 12;
    sym_key_length = 16;
    tag_length = 16;
    k_length = 32;
    break;
  default:
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Unsupported encryption algorithm");
    return -1;
  } // End of 'switch' statement
  
  // Convert the peer public encryption key to an EC point
  EC_POINT *ec_point = nullptr;
@@ -207,9 +224,8 @@ 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: _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> k_enc(nonce_length + sym_key_length + tag_length, 0x00);
  std::vector<unsigned char> k_mac(k_length + k_length, 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) {
@@ -219,18 +235,18 @@ 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: digest: ", digest.data(), digest.size());

  // Extract AES 128 parameters
  _nonce.resize(12); // TODO Use ec_encryption_algorithm
  _nonce.resize(nonce_length);
  std::copy(digest.begin(), digest.begin() + _nonce.size(), _nonce.begin());
  loggers::get_instance().log_to_hexa("security_ecc::generate_and_derive_ephemeral_key: _nonce: ", _nonce.data(), _nonce.size());
  _sym_key.resize(16);
  _sym_key.resize(sym_key_length);
  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);
  _tag.resize(tag_length);
  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);
  std::copy(digest.data() + 44, digest.data() + 44 + 32 + 32, hmac_secret.begin());
  std::vector<unsigned char> hmac_secret(k_length + k_length, 0x00);
  std::copy(digest.data() + nonce_length + sym_key_length + tag_length, digest.data() + nonce_length + sym_key_length + tag_length + 2 * k_length, hmac_secret.begin());
  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
@@ -259,6 +275,23 @@ 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);
  unsigned int nonce_length;
  unsigned int sym_key_length;
  unsigned int tag_length;
  unsigned int k_length;
  switch (_encryption_algotithm) {
  case encryption_algotithm::aes_128_ccm:
    // No break;
  case encryption_algotithm::aes_128_gcm:
    nonce_length = 12;
    sym_key_length = 16;
    tag_length = 16;
    k_length = 32;
    break;
  default:
    loggers::get_instance().warning("security_ecc::generate_and_derive_ephemeral_key: Unsupported encryption algorithm");
    return -1;
  } // End of 'switch' statement
  
  // Convert the peer public encryption key to an EC point
  EC_POINT *ec_point = nullptr;
@@ -273,9 +306,8 @@ 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: _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> k_enc(nonce_length + sym_key_length + tag_length, 0x00);
  std::vector<unsigned char> k_mac(k_length + k_length, 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) {
@@ -285,13 +317,13 @@ 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: digest: ", digest.data(), digest.size());

  // Extract AES 128 parameters
  std::vector<unsigned char> nonce(12, 0x00); // TODO Use ec_encryption_algorithm
  std::vector<unsigned char> nonce(nonce_length, 0x00);
  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::vector<unsigned char> sym_key(sym_key_length, 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::vector<unsigned char> tag(tag_length, 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());

@@ -301,8 +333,8 @@ int security_ecc::generate_and_derive_ephemeral_key(const encryption_algotithm p
  }
  
  // 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());
  std::vector<unsigned char> hmac_secret(k_length + k_length, 0x00);
  std::copy(digest.data() + nonce_length + sym_key_length + tag_length, digest.data() + nonce_length + sym_key_length + tag_length + 2 * k_length, 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
@@ -573,7 +605,7 @@ const int security_ecc::init() {
  ::ERR_load_crypto_strings();

  int result = -1;
  switch (_elliptic_curve) { // TODO Group this cde into a private  method
  switch (_elliptic_curve) {
  case ec_elliptic_curves::nist_p_256: // Use the ANSI X9.62 Prime 256v1 curve 
    result = ::OBJ_txt2nid("prime256v1");
    break;