Commit ad9c6578 authored by garciay's avatar garciay
Browse files

STF538: Start Encryption TPs implementation

        Start Certificate generation script
parent dd0fa58b
Loading
Loading
Loading
Loading
+17 −51
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@

#include "ec_keys.hh"

#include "loggers.hh" // To be remove to build a security shared library
#include "loggers.hh"

ec_keys::ec_keys(const ec_elliptic_curves p_elliptic_curve): _elliptic_curve(p_elliptic_curve), _encryption_algotithm(encryption_algotithm::aes_128_ccm), _ec_key(nullptr), _ec_group(nullptr), _bn_ctx(nullptr), _pri_key(), _pub_key_x(), _pub_key_y(), _eph_key(), _enc_key_x(), _enc_key_y(), _nonce(), _tag() {
  loggers::get_instance().log(">>> ec_keys::ec_keys: %d", static_cast<int>(p_elliptic_curve));
@@ -174,14 +174,16 @@ int ec_keys::generate() {
  return 0;
}

/*int ec_keys::generate_ephemeral_key(const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y) { // TODO Move it into encrypt
  printf(">>> ec_keys::generate_ephemeral_key (1)");
int ec_keys::generate_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y, int p_unused) {
  loggers::get_instance().log(">>> ec_keys::generate_ephemeral_key (1)");

  // Sanity checks
  if ((_pub_key_x.size() != 0) || (_pub_key_y.size() != 0)) {
    printf("ec_keys::generate_ephemeral_key: Constrictor format #1 shall be used");
    return -1;
  }
  p_unused = 0;
  _encryption_algotithm = p_enc_algorithm;
  ::EC_KEY_generate_key(_ec_key);
  
  // Set buffers size
@@ -202,25 +204,22 @@ int ec_keys::generate() {
  // Write the ephemeral key's public key to the output buffer
  std::vector<unsigned char> enc_key;
  public_key_to_bin(enc_key);
  dump_hexa("encryption_key: ", enc_key.data(), enc_key.size());
  // Extract X-coordinate and Y-coordinate
  _enc_key_x.assign(1 + enc_key.cbegin(), 1 + len + enc_key.cbegin());
  _enc_key_y.assign(1 + len + enc_key.cbegin(), enc_key.cend());
  
  return 0;
  }*/
}

/*int ec_keys::generate_ephemeral_key(encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_enc_key_x, const std::vector<unsigned char>& p_public_enc_key_y, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag) { // TODO Change it into ctor
  printf(">>> ec_keys::generate_ephemeral_key (2)");
int ec_keys::generate_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_enc_key_x, const std::vector<unsigned char>& p_public_enc_key_y) { // TODO Change it into ctor
  loggers::get_instance().log(">>> ec_keys::generate_ephemeral_key (2)");

  // Sanity checks
  if ((_pub_key_x.size() == 0) || (_pub_key_y.size() == 0)) {
  if (_pri_key.size() == 0) {
    printf("ec_keys::generate_ephemeral_key: Constrictor format #2 shall be used");
    return -1;
  }
  _encryption_algotithm = p_enc_algorithm;
  _nonce = p_nonce;
  _tag = p_tag;
  
  // Set buffers size
  int len = (EC_GROUP_get_degree(_ec_group) + 7) / 8;
@@ -238,9 +237,9 @@ int ec_keys::generate() {
  ::EC_POINT_free(ec_point);
  
  return 0;
  }*/
}

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

  // Sanity checks
@@ -248,28 +247,7 @@ int ec_keys::encrypt(const encryption_algotithm p_enc_algorithm, const std::vect
    loggers::get_instance().error("ec_keys::encrypt: Constructor format #1 shall be used");
    return -1;
  }
  _encryption_algotithm = p_enc_algorithm;
  ::EC_KEY_generate_key(_ec_key);
  
  // Set buffers size
  int len = (EC_GROUP_get_degree(_ec_group) + 7) / 8;
  _eph_key.resize(len);
  // Convert the public keys (X,Y) into EC_POINT data structure
  EC_POINT *ec_point = nullptr;
  bin_to_ec_point(p_public_key_x, p_public_key_y, &ec_point);
  // Generate the shared symmetric key
  int result = ::ECDH_compute_key(_eph_key.data(), _eph_key.size(), ec_point, _ec_key, NULL);
  if (result == -1) {
    ::EC_POINT_free(ec_point);
    return -1;
  }
  ::EC_POINT_free(ec_point);
  // Write the ephemeral key's public key to the output buffer
  std::vector<unsigned char> enc_key;
  public_key_to_bin(enc_key);
  // Extract X-coordinate and Y-coordinate
  _enc_key_x.assign(1 + enc_key.cbegin(), 1 + len + enc_key.cbegin());
  _enc_key_y.assign(1 + len + enc_key.cbegin(), enc_key.cend());
  // Initialize the context and encryption operation
  EVP_CIPHER_CTX *ctx = ::EVP_CIPHER_CTX_new();
  switch (_encryption_algotithm) {
@@ -300,6 +278,7 @@ int ec_keys::encrypt(const encryption_algotithm p_enc_algorithm, const std::vect
  ::EVP_EncryptInit_ex(ctx, NULL, NULL, _eph_key.data(), _nonce.data());
  // No authentication data
  // Encrypt the data
  int len = 0;
  ::EVP_EncryptUpdate(ctx, p_enc_message.data(), &len, p_message.data(), p_message.size());
  // Finalize the encryption session
  ::EVP_EncryptFinal_ex(ctx, p_enc_message.data() + len, &len);
@@ -311,31 +290,17 @@ int ec_keys::encrypt(const encryption_algotithm p_enc_algorithm, const std::vect
  return 0;
}

int ec_keys::decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_enc_key_x, const std::vector<unsigned char>& p_public_enc_key_y, 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) {
int ec_keys::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(">>> ec_keys::decrypt");

  // Sanity checks
  if ((_pub_key_x.size() == 0) || (_pub_key_y.size() == 0)) {
    loggers::get_instance().error("ec_keys::decrypt: Constrictor format #2 shall be used");
  if ((_pri_key.size() == 0) || (_eph_key.size() == 0)) {
    printf("ec_keys::decrypt: Constrictor format #2 shall be used");
    return -1;
  }
  _encryption_algotithm = p_enc_algorithm;
  _nonce = p_nonce;
  _tag = p_tag;
  
  // Set buffers size
  int len = (EC_GROUP_get_degree(_ec_group) + 7) / 8;
  _eph_key.resize(len);
  // Convert the peer public encryption key to an EC point
  EC_POINT *ec_point = nullptr;
  bin_to_ec_point(p_public_enc_key_x, p_public_enc_key_y, &ec_point);
  // Generate the shared symmetric key
  int result = ::ECDH_compute_key(_eph_key.data(), _eph_key.size(), ec_point, _ec_key, NULL);
  if (result == -1) {
    ::EC_POINT_free(ec_point);
    return -1;
  }
  ::EC_POINT_free(ec_point);
  // Initialize the context and decryption operation
  EVP_CIPHER_CTX *ctx = ::EVP_CIPHER_CTX_new();
  switch (_encryption_algotithm) {
@@ -360,7 +325,8 @@ int ec_keys::decrypt(const encryption_algotithm p_enc_algorithm, const std::vect
  EVP_DecryptInit_ex(ctx, NULL, NULL, _eph_key.data(), _nonce.data());
  // Decrypt plaintext, verify tag: can only be called once
  p_message.resize(p_enc_message.size());
  result = EVP_DecryptUpdate(ctx, p_message.data(), &len, p_enc_message.data(), p_enc_message.size());
  int len = 0;
  int result = EVP_DecryptUpdate(ctx, p_message.data(), &len, p_enc_message.data(), p_enc_message.size());
  ::EVP_CIPHER_CTX_free(ctx);
  
  return (result > 0) ? 0 : -1;
+38 −6
Original line number Diff line number Diff line
@@ -71,14 +71,46 @@ public:
   */ 
  virtual ~ec_keys();

  /*!
   * \fn int generate();
   * \brief Generate a pair (PrivateK, PublicK) of keys for signature or encryption
   * \return 0 on success, -1 otherwise
   * \remark To get the generated keys, \see private_key, public_key_x and public_key_y methods
   */ 
  int generate();
  /*!
   * \fn int sign(const std::vector<unsigned char>& p_data, std::vector<unsigned char>& p_r_sig, std::vector<unsigned char>& p_s_sig);
   * \brief Signed the data using ECDSA algorithm
   * \param[in] p_data The data to be signed
   * \param[out] p_r_sig Part of the signature
   * \param[out] p_s_sig Part of the signature
   * \return 0 on success, -1 otherwise
   */ 
  int sign(const std::vector<unsigned char>& p_data, std::vector<unsigned char>& p_r_sig, std::vector<unsigned char>& p_s_sig);
  /*!
   * \fn int sign_verif(const std::vector<unsigned char>& p_data, const std::vector<unsigned char>& p_signature);
   * \brief Verifiy an ECDSA signature
   * \param[in] p_data The signed data
   * \param[in] p_signature The signature part, based on r_sig part and s_sig part
   * \return 0 on success, -1 otherwise
   */ 
  int sign_verif(const std::vector<unsigned char>& p_data, const std::vector<unsigned char>& p_signature);
  /*!
   * \fn int generate_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y, int p_unused)
   * \brief Generate an ephemeral key for the next symmetric AES encryption
   * \param[in] p_enc_algorithm
   * \param[in] p_public_key_x
   * \param[in] p_public_key_y
   * \remark To get the generated ephemeral key, uses \see ephemeral_key method
   * \return 0 on success, -1 otherwise
   */ 
  int generate_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y, int p_unused);
  int generate_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_enc_key_x, const std::vector<unsigned char>& p_public_enc_key_y);
  int encrypt_ephemeral_key(const std::vector<unsigned char>& p_eph_key, std::vector<unsigned char>& p_enc_eph_key) { p_enc_eph_key = p_eph_key; return 0; }; // FIXME
  int decrypt_ephemeral_key(const std::vector<unsigned char>& p_enc_eph_key, std::vector<unsigned char>& p_eph_key) { p_eph_key = p_enc_eph_key; return 0; }; // FIXME

  //  int generate_ephemeral_key(const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y);
  //  int generate_ephemeral_key(encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_enc_key_x, const std::vector<unsigned char>& p_public_enc_key_y, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_tag);
  int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message);
  int decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_public_enc_key_x, const std::vector<unsigned char>& p_public_enc_key_y, 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);
  int encrypt(const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message);
  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);
  
  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; };