Commit 0a0fd492 authored by garciay's avatar garciay
Browse files

STF525: Add encryption support in Test System

STF545: Start TestSystem support
parent b5ab01db
Loading
Loading
Loading
Loading
+27 −6
Original line number Diff line number Diff line
@@ -305,11 +305,11 @@ namespace LibItsSecurity__Functions
  }
  
  /**
   * \fn OCTETSTRING fx__test__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt);
   * \fn OCTETSTRING fx__test__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct);
   * \brief Encrypt the message using AES 128 CCM algorithm
   * \param[in] p__k The symmetric encryption key
   * \param[in] p__n The initial vector, nonce vector
   * \param[in] pp__ct__pt The encrypted message concatenated to the AES 128 CCM tag
   * \param[in] p__ct The encrypted message concatenated to the AES 128 CCM tag
   * \return The original message
   */
  OCTETSTRING fx__test__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct) {
@@ -340,9 +340,14 @@ namespace LibItsSecurity__Functions
  /**
   * \fn OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyX, const OCTETSTRING& p__recipientsPublicKeyY, OCTETSTRING& p__publicEphemeralKeyX, OCTETSTRING& p__publicEphemeralKeyY, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce);
   * \brief Encrypt the message using ECIES algprithm to encrypt AES 128 CCM symmetric key, as defined in IEEE Std 1609.2-2017
   * \param[in] p__k The symmetric encryption key
   * \param[in] p__n The initial vector, nonce vector
   * \param[in] pp__ct__pt The encrypted message concatenated to the AES 128 CCM tag
   * \param[in] p__toBeEncryptedSecuredMessage The message to be encrypted
   * \param[in] p__recipientsPublicKeyX The public recipient's key X-coordinate
   * \param[in] p__recipientsPublicKeyV The public recipient's key Y-coordinate
   * \param[out] p__publicEphemeralKeyX The public ephemeral key X-coordinate
   * \param[out] p__publicEphemeralKeyY The public ephemeral key Y-coordinate
   * \param[out] p__encrypted__sym__key The encrypted AES 128 symmetric key
   * \param[out] p__authentication__vector The tag of the encrypted AES 128 symmetric key
   * \param[out] p__nonce The nonce vector
   * \return The original message
   * \see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
   * \see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
@@ -397,6 +402,22 @@ namespace LibItsSecurity__Functions
    return os;
  }

  /**
   * \fn OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyX, const OCTETSTRING& p__publicEphemeralKeyY, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce);
   * \brief Decrypt the message using ECIES algprithm to decrypt AES 128 CCM symmetric key, as defined in IEEE Std 1609.2-2017
   * \param[in] p__encryptedSecuredMessage The encrypted message
   * \param[in] p__privateEncKey The private encryption key
   * \param[in] p__publicEphemeralKeyX The public ephemeral key X-coordinate
   * \param[in] p__publicEphemeralKeyY The public ephemeral key Y-coordinate
   * \param[in] p__encrypted__sym__key The encrypted AES 128 symmetric key
   * \param[in] p__authentication__vector The tag of the encrypted AES 128 symmetric key
   * \param[in] p__nonce The nonce vector
   * \return The original message
   * \see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
   * \see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
   * \see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
   */
  // TODO Use common function for both fx__encryptWithEciesxxx and fx__decryptWithEciesxxx function
  OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__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);
@@ -421,7 +442,7 @@ namespace LibItsSecurity__Functions
      return OCTETSTRING();
    }
    
    // Decypt the message
    // Decrypt the message
    std::vector<unsigned char> enc_message(static_cast<const unsigned char*>(p__encryptedSecuredMessage), p__encryptedSecuredMessage.lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p__encryptedSecuredMessage));
    loggers::get_instance().log_to_hexa("fx__decryptWithEciesNistp256WithSha256: enc_message: ", enc_message.data(), enc_message.size());
    std::vector<unsigned char> tag(p__encryptedSecuredMessage.lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p__encryptedSecuredMessage), p__encryptedSecuredMessage.lengthof() + static_cast<const unsigned char*>(p__encryptedSecuredMessage));
+65 −23
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ int security_services::process_ieee_1609_dot2_content(const IEEE1609dot2::Ieee16
  } else if (p_ieee_1609_dot2_content.ischosen(IEEE1609dot2::Ieee1609Dot2Content::ALT_encryptedData)) {
    const IEEE1609dot2::EncryptedData& encrypted_data = p_ieee_1609_dot2_content.encryptedData();
    OCTETSTRING signed_payload;
    if (security_services::process_ieee_1609_dot2_encrypted_data(encrypted_data, p_verify, signed_payload, p_params) != 0) {
    if (process_ieee_1609_dot2_encrypted_data(encrypted_data, p_verify, signed_payload, p_params) != 0) {
      if (p_verify) {
        return -1;
      }
@@ -384,31 +384,73 @@ int security_services::process_ieee_1609_dot2_signed_data(const IEEE1609dot2::Si
int security_services::process_ieee_1609_dot2_encrypted_data(const IEEE1609dot2::EncryptedData& p_encrypted_data, const bool p_verify, OCTETSTRING& p_unsecured_payload, Params& p_params) {
  loggers::get_instance().log_msg(">>> security_services::process_ieee_1609_dot2_encrypted_data: ", p_encrypted_data);
  

  if (_params[Params::cypher].compare("NISTP-256") == 0) {
	  _ec_keys_enc.reset(new security_ecc(ec_elliptic_curves::nist_p_256));
  } else if (_params[Params::cypher].compare("BP-256") == 0) {
	  _ec_keys_enc.reset(new security_ecc(ec_elliptic_curves::brainpool_p_256_r1));
  // 1. Retrieve the RecipientId
  const IEEE1609dot2::RecipientInfo& r = p_encrypted_data.recipients()[0]; // TODO Add multiple support of recipients
  const IEEE1609dot2BaseTypes::EciesP256EncryptedKey* ecies = nullptr; // TODO Use smart pointer
  const OCTETSTRING* recipient_id = nullptr; // TODO Use smart pointer
  if (r.ischosen(IEEE1609dot2::RecipientInfo::ALT_certRecipInfo)) {
    recipient_id = &r.certRecipInfo().recipientId();
    if (r.certRecipInfo().encKey().ischosen(IEEE1609dot2::EncryptedDataEncryptionKey::ALT_eciesNistP256)) {
      ecies = &r.certRecipInfo().encKey().eciesNistP256();
    } else if (r.certRecipInfo().encKey().ischosen(IEEE1609dot2::EncryptedDataEncryptionKey::ALT_eciesBrainpoolP256r1)) {
      ecies = &r.certRecipInfo().encKey().eciesBrainpoolP256r1();
    } else {
    loggers::get_instance().warning("security_services::setup: Failed to encode ToBeSignedData");
      loggers::get_instance().warning("security_services::process_ieee_1609_dot2_encrypted_data: Unsupported encryption algorithm");
      return -1;
    }
  } else {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_encrypted_data: Unsupported RecipientInfo variant");
    return -1;
  }
  if (!ecies->v().ischosen(IEEE1609dot2BaseTypes::EccP256CurvePoint::ALT_uncompressedP256)) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_encrypted_data: Unsupported EccP256CurvePoint variant");
    return -1;
  }
  if (!p_encrypted_data.ciphertext().ischosen(IEEE1609dot2::SymmetricCiphertext::ALT_aes128ccm)) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_encrypted_data: Unsupported AES 128 algorithm");
    return -1;
  }
  
  // 2. Retrieve the certificate if present
  std::string certificate_id;
  if (_security_db.get()->get_certificate_id(*recipient_id, certificate_id) == -1) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_encrypted_data: Unknown certificate");
    // TODO Setup request certificate mechanism
    return -1;
  }
  OCTETSTRING p_enc_key;
  if (_security_db.get()->get_private_enc_key(certificate_id, p_enc_key) == -1) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_encrypted_data: Failed to retrieve private encryption key");
    return -1;
  }
  std::vector<unsigned char> private_enc_key(static_cast<const unsigned char*>(p_enc_key), p_enc_key.lengthof() + static_cast<const unsigned char*>(p_enc_key));

  // 3. Generate the shared secret value based on recipient's public ephemeral keys will be required
  security_ecc ec(ec_elliptic_curves::nist_p_256, private_enc_key);
  std::vector<unsigned char> ephemeral_public_key_x(static_cast<const unsigned char*>(ecies->v().uncompressedP256().x()), ecies->v().uncompressedP256().x().lengthof() + static_cast<const unsigned char*>(ecies->v().uncompressedP256().x()));
  std::vector<unsigned char> ephemeral_public_key_y(static_cast<const unsigned char*>(ecies->v().uncompressedP256().y()), ecies->v().uncompressedP256().y().lengthof() + static_cast<const unsigned char*>(ecies->v().uncompressedP256().y()));
  std::vector<unsigned char> enc_sym_key(static_cast<const unsigned char*>(ecies->c()), ecies->c().lengthof() + static_cast<const unsigned char*>(ecies->c()));
  std::vector<unsigned char> nonce(static_cast<const unsigned char*>(p_encrypted_data.ciphertext().aes128ccm().nonce()), p_encrypted_data.ciphertext().aes128ccm().nonce().lengthof() + static_cast<const unsigned char*>(p_encrypted_data.ciphertext().aes128ccm().nonce()));
  std::vector<unsigned char> authentication_vector(static_cast<const unsigned char*>(ecies->t()), ecies->t().lengthof() + static_cast<const unsigned char*>(ecies->t()));
  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("security_services::process_ieee_1609_dot2_encrypted_data: Failed to generate shared secret");
    return -1;
  }

  // 1. Retrieve recipient's public keys
  // OCTETSTRING recipients_key_x;
  // OCTETSTRING recipients_key_y;
  // if (_security_db.get()->get_public_enc_keys(certificate_id, recipients_key_x, recipients_key_y) == -1) {
  //   loggers::get_instance().warning("security_services::encrypt_gn_payload: Failed to retrieve recipient's public keys");
  //   return -1;
  // }




  loggers::get_instance().log_msg("<<< security_services::process_ieee_1609_dot2_encrypted_data: ", p_unsecured_payload);
  // 4. Decrypt the message
  std::vector<unsigned char> enc_message(static_cast<const unsigned char*>(p_encrypted_data.ciphertext().aes128ccm().ccmCiphertext()), p_encrypted_data.ciphertext().aes128ccm().ccmCiphertext().lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p_encrypted_data.ciphertext().aes128ccm().ccmCiphertext()));
  loggers::get_instance().log_to_hexa("security_services::process_ieee_1609_dot2_encrypted_data: enc_message: ", enc_message.data(), enc_message.size());
  std::vector<unsigned char> tag(p_encrypted_data.ciphertext().aes128ccm().ccmCiphertext().lengthof() - ec.tag().size() + static_cast<const unsigned char*>(p_encrypted_data.ciphertext().aes128ccm().ccmCiphertext()), p_encrypted_data.ciphertext().aes128ccm().ccmCiphertext().lengthof() + static_cast<const unsigned char*>(p_encrypted_data.ciphertext().aes128ccm().ccmCiphertext()));
  loggers::get_instance().log_to_hexa("security_services::process_ieee_1609_dot2_encrypted_data: tag: ", tag.data(), tag.size());
  std::vector<unsigned char> message;
  if (ec.decrypt(tag, enc_message, message) == -1) {
    loggers::get_instance().warning("security_services::process_ieee_1609_dot2_encrypted_data: Failed to generate shared secret");
    return -1;
  }
  p_unsecured_payload = OCTETSTRING(message.size(), message.data());
  loggers::get_instance().log_msg("security_services::process_ieee_1609_dot2_encrypted_data: ", p_unsecured_payload);
  
  return 0;
} // End of method process_ieee_1609_dot2_encrypted_data

int security_services::secure_gn_payload(const OCTETSTRING& p_unsecured_gn_payload, OCTETSTRING& p_secured_gn_payload, Params& p_params) {