Commit 9b48588f authored by Yann Garcia's avatar Yann Garcia
Browse files

Enhance BFK support

parent 00276905
Loading
Loading
Loading
Loading
+98 −112
Original line number Diff line number Diff line
@@ -1123,52 +1123,6 @@ const int security_ecc::init() {
  return 0;
} // End of init

int security_ecc::bin_to_ec_point(const OCTETSTRING &p_public_key_x, const OCTETSTRING &p_public_key_y,
                                  EC_POINT **p_ec_point) { // ec_key_public_key_bin_to_point
  BIGNUM *pubk_bn;

  OCTETSTRING v = int2oct(4, 1);
  v += p_public_key_x;
  v += p_public_key_y;

  pubk_bn     = ::BN_bin2bn(static_cast<const unsigned char *>(v), v.lengthof(), nullptr);
  *p_ec_point = ::EC_POINT_new(_ec_group);
  ::EC_POINT_bn2point(_ec_group, pubk_bn, *p_ec_point, _bn_ctx);
  ::BN_clear_free(pubk_bn);

  return 0;
}

int security_ecc::public_key_to_bin(OCTETSTRING &p_bin_key) { // ec_key_public_key_to_bin
  const EC_POINT *pub      = ::EC_KEY_get0_public_key(_ec_key);
  BIGNUM *pub_bn   = ::BN_new();

  ::EC_POINT_point2bn(_ec_group, pub, POINT_CONVERSION_UNCOMPRESSED, pub_bn, _bn_ctx);
  p_bin_key = int2oct(0, BN_num_bytes(pub_bn));
  ::BN_bn2bin(pub_bn, (unsigned char *)static_cast<const unsigned char *>(p_bin_key));

  ::BN_free(pub_bn);

  return 0;
}

void security_ecc::ec_point_print(const std::string& p_label, const EC_POINT *p_key) {
    BIGNUM * x = ::BN_new();
    BIGNUM * y = ::BN_new();
    ::EC_POINT_get_affine_coordinates(_ec_group, p_key, x, y, NULL);
    char* sx = ::BN_bn2hex(x);
    char* sy = ::BN_bn2hex(y);
    loggers::get_instance().log("%sx=%s\ny=%s\n", p_label.c_str(), sx, sy);
    free(sx); free(sy);
    ::BN_free(x); ::BN_free(y);
}

void security_ecc::bn_print(const std::string& p_label, const BIGNUM* p_num) {
    char* s = ::BN_bn2hex(p_num);
    loggers::get_instance().log("%s:%s", p_label.c_str(), s);
    free(s);
}

int security_ecc::kdf2(const OCTETSTRING &p_secret_key, const OCTETSTRING &p_salt, const unsigned char p_hash_algorithm, const int p_key_length,
                       OCTETSTRING &p_digest) {
  loggers::get_instance().log(">>> security_ecc::kdf2");
@@ -1400,64 +1354,31 @@ int security_ecc::bfk_expend_private_key(const OCTETSTRING& p_expansion_key, con
  return 0;
}

int security_ecc::bfk_expend_public_key(const OCTETSTRING& p_expansion_key, const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode, OCTETSTRING& p_expended_compressed_publi_key, INTEGER& p_expended_compressed_mode) {
int security_ecc::bfk_expend_public_key(const OCTETSTRING& p_expansion_key, const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode, OCTETSTRING& p_expended_compressed_public_key, INTEGER& p_expended_compressed_mode) {
  loggers::get_instance().log_msg(">>> security_ecc::bfk_expend_public_key: p_expansion_key: ", p_expansion_key);
  loggers::get_instance().log_msg(">>> security_ecc::bfk_expend_public_key: p_compressed_public_key: ", p_compressed_public_key);
  loggers::get_instance().log_msg(">>> security_ecc::bfk_expend_public_key: p_compressed_mode: ", p_compressed_mode);

  // P1609.2.1/D7, January 2022 Clause 9.3.4.2.1 General
  // Bi, j = A + ft(kt, i, j) × G or Qi, j = P + ft(kt, i, j) × G, B = signing_expension_key * G

  // Convert compressed key into uncompressed key
  // TODO Create a function uncompressed to copmpressed ec_point
  // TODO Create a function ec_point to compressed bin and to uncompressed bin
  EC_POINT* A;
  compressed_key_to_ec_point(p_compressed_public_key, p_compressed_mode, &A);
  // {
  //   BIGNUM* compressed_key = ::BN_new();
  //   ::BN_bin2bn(static_cast<const unsigned char *>(p_compressed_public_key), p_compressed_public_key.lengthof(), compressed_key);
  //   int result = ::EC_POINT_set_compressed_coordinates_GFp(_ec_group, A, compressed_key, (p_compressed_mode == static_cast<int>(ecc_compressed_mode::compressed_y_1)) ? 1 : 0, _bn_ctx); // Use primary elliptic curve
  //   ::BN_free(compressed_key);
  //   // Set public keys
  //   BIGNUM *xy = ::BN_new();
  //   ::EC_POINT_point2bn(_ec_group, A, POINT_CONVERSION_UNCOMPRESSED, xy, _bn_ctx);
  //   if (BN_num_bytes(xy) == 0) {
  //     ::BN_free(xy);
  //     loggers::get_instance().error("security_ecc::bfk_expend_public_key: Failed to generate xy coordinates, check algorithms");
  //     return -1;
  //   }
  //   loggers::get_instance().log("security_ecc::bfk_expend_public_key: xy length: %d", BN_num_bytes(xy));
  //   bn_print("security_ecc::bfk_expend_public_key: xy: ", xy);
  //   ::BN_free(xy);
  // }
  EC_POINT* A; // Public key as defined in P1609.2.1/D7, January 2022 Clause 9.3.4.2.1 General
  int res = compressed_key_to_ec_point(p_compressed_public_key, p_compressed_mode, &A);
  ec_point_print("A: ", A);

  BIGNUM* expansion_key = ::BN_new();
  ::BN_bin2bn(static_cast<const unsigned char *>(p_expansion_key), p_expansion_key.lengthof(), expansion_key);
  EC_POINT* B = ::EC_POINT_new(_ec_group);
  int res = ::EC_POINT_mul(_ec_group, B, expansion_key, NULL, NULL, _bn_ctx);
  res = ::EC_POINT_mul(_ec_group, B, expansion_key, NULL, NULL, _bn_ctx);
  // A + f_k(x_cert)*G_P256 mod l
  EC_POINT* A_exp = EC_POINT_new(_ec_group);
  EC_POINT* A_exp = EC_POINT_new(_ec_group); // Expanded public key as defined in P1609.2.1/D7, January 2022 Clause 9.3.4.2.1 General
  res = ::EC_POINT_add(_ec_group, A_exp, A, B, _bn_ctx);
  ec_point_print("A_exp: ", A_exp);

  // Convert EC_POINT into compressed mode
  OCTETSTRING os;
  {
  const EC_POINT *pub = ::EC_KEY_get0_public_key(_ec_key);
  BIGNUM *bn_A_exp = ::BN_new();
  ::EC_POINT_point2bn(_ec_group, A_exp, POINT_CONVERSION_COMPRESSED, bn_A_exp, _bn_ctx);
  bn_print("security_ecc::bfk_expend_public_key: ", bn_A_exp);
  os = int2oct(0, BN_num_bytes(bn_A_exp));
  ::BN_bn2bin(bn_A_exp, (unsigned char *)static_cast<const unsigned char *>(os));
  ::BN_free(bn_A_exp);
  }
  p_expended_compressed_mode = (static_cast<int>(os[0].get_octet()) == 0x02) ? 0 : 1;
  p_expended_compressed_publi_key = OCTETSTRING(os.lengthof() - 1, static_cast<const unsigned char *>(os) + 1);
  loggers::get_instance().log_msg("security_ecc::generate_bkf_enc_expension_keys: p_expended_compressed_publi_key: ", p_expended_compressed_publi_key);
  res = ec_point_to_compressed_key(A_exp, p_expended_compressed_public_key, p_expended_compressed_mode);
  loggers::get_instance().log_msg("security_ecc::generate_bkf_enc_expension_keys: p_expended_compressed_public_key: ", p_expended_compressed_public_key);
  loggers::get_instance().log_msg("security_ecc::generate_bkf_enc_expension_keys: p_expended_compressed_mode: ", p_expended_compressed_mode);


  ::BN_free(expansion_key);
  ::EC_POINT_free(A_exp);
  ::EC_POINT_free(A);
@@ -1467,9 +1388,9 @@ int security_ecc::bfk_expend_public_key(const OCTETSTRING& p_expansion_key, cons
}

boolean security_ecc::bfk_verify_expended_keys(const OCTETSTRING& p_private_key, const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode) {
  loggers::get_instance().log_msg(">>> bfk_verify_expended_keys: p_private_key: ", p_private_key);
  loggers::get_instance().log_msg(">>> bfk_verify_expended_keys: p_compressed_public_key: ", p_compressed_public_key);
  loggers::get_instance().log_msg(">>> bfk_verify_expended_keys: p_compressed_mode: ", p_compressed_mode);
  loggers::get_instance().log_msg(">>> security_ecc::bfk_verify_expended_keys: p_private_key: ", p_private_key);
  loggers::get_instance().log_msg(">>> security_ecc::bfk_verify_expended_keys: p_compressed_public_key: ", p_compressed_public_key);
  loggers::get_instance().log_msg(">>> security_ecc::bfk_verify_expended_keys: p_compressed_mode: ", p_compressed_mode);

  BIGNUM* a_exp = BN_new();
  ::BN_bin2bn((unsigned char *)static_cast<const unsigned char *>(p_private_key), p_private_key.lengthof(), a_exp);
@@ -1488,28 +1409,6 @@ boolean security_ecc::bfk_verify_expended_keys(const OCTETSTRING& p_private_key,
  return res;
}

int security_ecc::compressed_key_to_ec_point(const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode, EC_POINT** p_ec_point) {
  *p_ec_point = ::EC_POINT_new(_ec_group);

  BIGNUM* compressed_key = ::BN_new();
  ::BN_bin2bn(static_cast<const unsigned char *>(p_compressed_public_key), p_compressed_public_key.lengthof(), compressed_key);
  int result = ::EC_POINT_set_compressed_coordinates_GFp(_ec_group, *p_ec_point, compressed_key, (p_compressed_mode == static_cast<int>(ecc_compressed_mode::compressed_y_1)) ? 1 : 0, _bn_ctx); // Use primary elliptic curve
  ::BN_free(compressed_key);
  // Set public keys
  BIGNUM *xy = ::BN_new();
  ::EC_POINT_point2bn(_ec_group, *p_ec_point, POINT_CONVERSION_UNCOMPRESSED, xy, _bn_ctx);
  if (BN_num_bytes(xy) == 0) {
    ::BN_free(xy);
    loggers::get_instance().error("security_ecc::bfk_expend_public_key: Failed to generate xy coordinates, check algorithms");
    return -1;
  }
  loggers::get_instance().log("security_ecc::bfk_expend_public_key: xy length: %d", BN_num_bytes(xy));
  bn_print("security_ecc::bfk_expend_public_key: xy: ", xy);
  ::BN_free(xy);

  return 0;
}

int security_ecc::bkf_expension_function(const encryption_algotithm p_enc_algorithm, const unsigned char* p_random_signing_aes_enc_key, const unsigned char* p_expension_key, const size_t p_key_len, unsigned char** p_bin_result) {
  loggers::get_instance().log(">>> security_ecc::bkf_expension_function");

@@ -1575,3 +1474,90 @@ int security_ecc::bkf_expension_function(const encryption_algotithm p_enc_algori

  return 32;
}

int security_ecc::ec_point_to_compressed_key(const EC_POINT* p_ec_point, OCTETSTRING& p_compressed_public_key, INTEGER& p_compressed_mode) {
  loggers::get_instance().log(">>> security_ecc::ec_point_to_compressed_key: p_private_key");
  ec_point_print("security_ecc::ec_point_to_compressed_key: p_ec_point: ", p_ec_point);

  const EC_POINT *pub = ::EC_KEY_get0_public_key(_ec_key);
  BIGNUM *bn_compressed_key = ::BN_new();
  ::EC_POINT_point2bn(_ec_group, p_ec_point, POINT_CONVERSION_COMPRESSED, bn_compressed_key, _bn_ctx);
  bn_print("security_ecc::ec_point_to_compressed_key: bn_compressed_key: ", bn_compressed_key);
  OCTETSTRING os = int2oct(0, BN_num_bytes(bn_compressed_key));
  ::BN_bn2bin(bn_compressed_key, (unsigned char *)static_cast<const unsigned char *>(os));
  ::BN_free(bn_compressed_key);
  p_compressed_mode = (static_cast<int>(os[0].get_octet()) == 0x02) ? 0 : 1;
  p_compressed_public_key = OCTETSTRING(os.lengthof() - 1, static_cast<const unsigned char *>(os) + 1);
  loggers::get_instance().log_msg("security_ecc::ec_point_to_compressed_key: p_compressed_public_key: ", p_compressed_public_key);
  loggers::get_instance().log_msg("security_ecc::ec_point_to_compressed_key: p_compressed_mode: ", p_compressed_mode);

  return 0;
}

int security_ecc::compressed_key_to_ec_point(const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode, EC_POINT** p_ec_point) {
  *p_ec_point = ::EC_POINT_new(_ec_group);

  BIGNUM* compressed_key = ::BN_new();
  ::BN_bin2bn(static_cast<const unsigned char *>(p_compressed_public_key), p_compressed_public_key.lengthof(), compressed_key);
  int result = ::EC_POINT_set_compressed_coordinates_GFp(_ec_group, *p_ec_point, compressed_key, (p_compressed_mode == static_cast<int>(ecc_compressed_mode::compressed_y_1)) ? 1 : 0, _bn_ctx); // Use primary elliptic curve
  ::BN_free(compressed_key);
  // Set public keys
  BIGNUM *xy = ::BN_new();
  ::EC_POINT_point2bn(_ec_group, *p_ec_point, POINT_CONVERSION_UNCOMPRESSED, xy, _bn_ctx);
  if (BN_num_bytes(xy) == 0) {
    ::BN_free(xy);
    loggers::get_instance().error("security_ecc::bfk_expend_public_key: Failed to generate xy coordinates, check algorithms");
    return -1;
  }
  loggers::get_instance().log("security_ecc::bfk_expend_public_key: xy length: %d", BN_num_bytes(xy));
  bn_print("security_ecc::bfk_expend_public_key: xy: ", xy);
  ::BN_free(xy);

  return 0;
}

int security_ecc::bin_to_ec_point(const OCTETSTRING &p_public_key_x, const OCTETSTRING &p_public_key_y,
                                  EC_POINT **p_ec_point) { // ec_key_public_key_bin_to_point
  BIGNUM *pubk_bn;

  OCTETSTRING v = int2oct(4, 1);
  v += p_public_key_x;
  v += p_public_key_y;

  pubk_bn     = ::BN_bin2bn(static_cast<const unsigned char *>(v), v.lengthof(), nullptr);
  *p_ec_point = ::EC_POINT_new(_ec_group);
  ::EC_POINT_bn2point(_ec_group, pubk_bn, *p_ec_point, _bn_ctx);
  ::BN_clear_free(pubk_bn);

  return 0;
}

int security_ecc::public_key_to_bin(OCTETSTRING &p_bin_key) { // ec_key_public_key_to_bin
  const EC_POINT *pub      = ::EC_KEY_get0_public_key(_ec_key);
  BIGNUM *pub_bn   = ::BN_new();

  ::EC_POINT_point2bn(_ec_group, pub, POINT_CONVERSION_UNCOMPRESSED, pub_bn, _bn_ctx);
  p_bin_key = int2oct(0, BN_num_bytes(pub_bn));
  ::BN_bn2bin(pub_bn, (unsigned char *)static_cast<const unsigned char *>(p_bin_key));

  ::BN_free(pub_bn);

  return 0;
}

void security_ecc::ec_point_print(const std::string& p_label, const EC_POINT *p_key) {
    BIGNUM * x = ::BN_new();
    BIGNUM * y = ::BN_new();
    ::EC_POINT_get_affine_coordinates(_ec_group, p_key, x, y, NULL);
    char* sx = ::BN_bn2hex(x);
    char* sy = ::BN_bn2hex(y);
    loggers::get_instance().log("%sx=%s\ny=%s\n", p_label.c_str(), sx, sy);
    free(sx); free(sy);
    ::BN_free(x); ::BN_free(y);
}

void security_ecc::bn_print(const std::string& p_label, const BIGNUM* p_num) {
    char* s = ::BN_bn2hex(p_num);
    loggers::get_instance().log("%s:%s", p_label.c_str(), s);
    free(s);
}
+17 −18
Original line number Diff line number Diff line
@@ -264,7 +264,7 @@ public: //! \publicsection

  int bfk_expend_private_key(const OCTETSTRING& p_expansion_key, const OCTETSTRING& p_private_key, OCTETSTRING& p_expended_private_key);

  int bfk_expend_public_key(const OCTETSTRING& p_expansion_key, const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode, OCTETSTRING& p_expended_compressed_publi_key, INTEGER& p_expended_compressed_mode);
  int bfk_expend_public_key(const OCTETSTRING& p_expansion_key, const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode, OCTETSTRING& p_expended_compressed_public_key, INTEGER& p_expended_compressed_mode);

  boolean bfk_verify_expended_keys(const OCTETSTRING& p_private_key, const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode);

@@ -295,23 +295,6 @@ private: //! \privatesection
   * \return 0 on success, -1 otherwise
   */
  const int init();
  /*!
   * \fn int bin_to_ec_point(const OCTETSTRING& p_public_key_x, const OCTETSTRING& p_public_key_y, EC_POINT** p_ec_point);
   * \brief Convert a big number object into a public key
   * \return 0 on success, -1 otherwise
   */
  int bin_to_ec_point(const OCTETSTRING &p_public_key_x, const OCTETSTRING &p_public_key_y, EC_POINT **p_ec_point);
  /*!
   * \fn int public_key_to_bin(OCTETSTRING& p_bin_key);
   * \brief Convert a public key into a big number object
   * \return 0 on success, -1 otherwise
   */
  int public_key_to_bin(OCTETSTRING &p_bin_key);

  void ec_point_print(const std::string& p_label, const EC_POINT *p_key);

  void bn_print(const std::string& p_label, const BIGNUM* p_num);

  int kdf2(const OCTETSTRING &p_secret_key, const OCTETSTRING &p_salt, const unsigned char p_hash_algorithm, const int p_key_length, OCTETSTRING &p_digest);
  int kdf2_sha256(const OCTETSTRING &p_secret_key, const OCTETSTRING &p_salt, const int p_key_length, OCTETSTRING &p_digest);

@@ -329,6 +312,22 @@ private: //! \privatesection
   */
  int bkf_expension_function(const encryption_algotithm p_enc_algorithm, const unsigned char* p_random_signing_aes_enc_key, const unsigned char* p_expension_key, const size_t p_key_len, unsigned char** p_bin_result);

  /*!
   * \fn int bin_to_ec_point(const OCTETSTRING& p_public_key_x, const OCTETSTRING& p_public_key_y, EC_POINT** p_ec_point);
   * \brief Convert a big number object into a public key
   * \return 0 on success, -1 otherwise
   */
  int bin_to_ec_point(const OCTETSTRING &p_public_key_x, const OCTETSTRING &p_public_key_y, EC_POINT **p_ec_point);
  int compressed_key_to_ec_point(const OCTETSTRING& p_compressed_public_key, const INTEGER& p_compressed_mode, EC_POINT** p_ec_point);
  int ec_point_to_compressed_key(const EC_POINT* p_ec_point, OCTETSTRING& p_compressed_public_key, INTEGER& p_compressed_mode);
  void ec_point_print(const std::string& p_label, const EC_POINT *p_key);
  /*!
   * \fn int public_key_to_bin(OCTETSTRING& p_bin_key);
   * \brief Convert a public key into a big number object
   * \return 0 on success, -1 otherwise
   */
  int public_key_to_bin(OCTETSTRING &p_bin_key);

  void bn_print(const std::string& p_label, const BIGNUM* p_num);

}; // End of class security_ecc
Compare 9490350e to f6566fcb
Original line number Diff line number Diff line
Subproject commit 9490350e9ef178c265ebc834faa1b9450a6f40e3
Subproject commit f6566fcbe3322e533dfa28ccd6e451603f151dae
Compare 110f8bb0 to f6bc9761
Original line number Diff line number Diff line
Subproject commit 110f8bb0b13637a495edead21b83c63d7d0ffcfd
Subproject commit f6bc9761e95a3ded6434cf1a7382fa7d5fbd2d9c