Skip to content
LibItsSecurity_externals.cc 68.3 KiB
Newer Older
/*!
 * \file      LibItsSecurity_Functions.cc
 * \brief     Source file for Security externl functions.
 * \author    ETSI STF525
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#include "LibItsSecurity_Functions.hh"

#include "sha256.hh"
#include "sha384.hh"
#include "hmac.hh"

#include "security_ecc.hh"

#include "security_services.hh"

#include <openssl/ec.h>
#include <openssl/ecdsa.h>

#include "loggers.hh"

namespace LibItsSecurity__Functions 
{

  // FIXME Unify code with security_services
  
  /**
   * \fn OCTETSTRING fx_hashWithSha256(const OCTETSTRING& p__toBeHashedData);
   * \brief Produces a 256-bit (32-bytes) hash value
   * \param[in] p__toBeHashedData The data to be used to calculate the hash value
   * \return  The hash value
   */
  OCTETSTRING fx__hashWithSha256(
                                 const OCTETSTRING& p__toBeHashedData
                                 ) {
    loggers::get_instance().log_msg(">>> fx__hashWithSha256: p__toBeHashedData= ", p__toBeHashedData); 
    sha256 hash;
    OCTETSTRING hashData;
    hash.generate(p__toBeHashedData, hashData);
    loggers::get_instance().log_msg("fx__hashWithSha256: hashData= ", hashData);
    return hashData;
  } // End of function fx__hashWithSha256

  /**
   * \fn OCTETSTRING fx_hashWithSha384(const OCTETSTRING& p__toBeHashedData);
   * \brief Produces a 384-bit (48-bytes) hash value
   * \param[in] p__toBeHashedData Data to be used to calculate the hash value
   * \return The hash value
   */
  OCTETSTRING fx__hashWithSha384(
                                 const OCTETSTRING& p__toBeHashedData
                                 ) {
    sha384 hash;
    OCTETSTRING hashData;
    hash.generate(p__toBeHashedData, hashData);
    loggers::get_instance().log_msg("fx__hashWithSha384: hashData= ", hashData);
    return hashData;
  } // End of function fx__hashWithSha384

  /**
   * \fn OCTETSTRING fx__signWithEcdsaNistp256WithSha256(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
  OCTETSTRING fx__signWithEcdsaNistp256WithSha256(
                                                  const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                  const OCTETSTRING& p__certificateIssuer,
                                                  const OCTETSTRING& p__privateKey
                                                  ) {
garciay's avatar
garciay committed
    loggers::get_instance().log_msg(">>> fx__signWithEcdsaNistp256WithSha256: data=", p__toBeSignedSecuredMessage); 
    loggers::get_instance().log_msg(">>> fx__signWithEcdsaNistp256WithSha256: issuer=", p__certificateIssuer); 
    loggers::get_instance().log_msg(">>> fx__signWithEcdsaNistp256WithSha256: private key=", p__privateKey); 
    
    // Sanity checks
    if ((p__certificateIssuer.lengthof() != 32) || (p__privateKey.lengthof() != 32)) {
      loggers::get_instance().log("fx__signWithEcdsaNistp256WithSha256: Wrong parameters");
      return OCTETSTRING(0, nullptr);
    }
    
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeSignedSecuredMessage, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      hashData2 = p__certificateIssuer;
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash (Data input) || Hash (Signer identifier input)=", hashData1);
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
    // Calculate the signature
    security_ecc k(ec_elliptic_curves::nist_p_256, p__privateKey);
    OCTETSTRING r_sig;
    OCTETSTRING s_sig;
    if (k.sign(hashData, r_sig, s_sig) == 0) {
      OCTETSTRING os = r_sig + s_sig;
      loggers::get_instance().log_msg("r_sig= ", r_sig);
      loggers::get_instance().log_msg("s_sig= ", s_sig);
      loggers::get_instance().log_msg("sig= ", os);
    return OCTETSTRING(0, nullptr);
  }

  /**
   * \fn OCTETSTRING fx__signWithEcdsaBrainpoolp256WithSha256(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
  OCTETSTRING fx__signWithEcdsaBrainpoolp256WithSha256(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__certificateIssuer,
                                                       const OCTETSTRING& p__privateKey
                                                       ) {
    // Sanity checks
    if ((p__certificateIssuer.lengthof() != 32) || (p__privateKey.lengthof() != 32)) {
      loggers::get_instance().log("fx__signWithEcdsaBrainpoolp256WithSha256: Wrong parameters");
      return OCTETSTRING(0, nullptr);
    }
    
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeSignedSecuredMessage, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
      hashData2 = p__certificateIssuer;
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp256WithSha256: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp256WithSha256: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
    hash.generate(hashData1, hashData);
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp256WithSha256: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
    // Calculate the signature
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, p__privateKey);
    OCTETSTRING r_sig;
    OCTETSTRING s_sig;
    if (k.sign(hashData, r_sig, s_sig) == 0) {
      OCTETSTRING os = r_sig + s_sig;
      loggers::get_instance().log_msg("r_sig= ", r_sig);
      loggers::get_instance().log_msg("s_sig= ", s_sig);
      loggers::get_instance().log_msg("sig= ", os);
    return OCTETSTRING(0, nullptr);
  }

  /**
   * \fn OCTETSTRING fx__signWithEcdsaBrainpoolp384WithSha384(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
  OCTETSTRING fx__signWithEcdsaBrainpoolp384WithSha384(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__certificateIssuer,
                                                       const OCTETSTRING& p__privateKey
                                                       ) {
    // Sanity checks
	    if ((p__certificateIssuer.lengthof() != 48) || (p__privateKey.lengthof() != 48)) {
      loggers::get_instance().log("fx__signWithEcdsaBrainpoolp384WithSha384: Wrong parameters");
      return OCTETSTRING(0, nullptr);
    }
    
    // Calculate the SHA384 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha384 hash;
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeSignedSecuredMessage, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
    if (p__certificateIssuer != int2oct(0, 48)) { // || Hash (Signer identifier input)
      hashData2 = p__certificateIssuer;
    } else {
      hashData2 = hash.get_sha384_empty_string(); // Hash of empty string
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: Hash (Signer identifier input)=", hashData2);
Loading full blame...