lib_its_security.h 25.3 KB
Newer Older
YannGarcia's avatar
YannGarcia committed
/*!
 * \File      lib_its_security.h
 * \brief     Declaration file for Security external functions.
 * \author    FSCOM
 * \copyright FSCOM 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
 */
#pragma once

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <memory.h>
#include <errno.h>

#include <openssl/err.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
#include <openssl/hmac.h>

/*!
 * \enum Supported Elliptic curves
 */
typedef enum ecc_elliptic_curves_ {
  nist_p_256,         /*!< NIST P-256, P-256, primve256v1 */
  brainpool_p_256_r1, /*!< Brainpool P256r1 */
  brainpool_p_384_r1  /*!< Brainpool P384r1 */
} ecc_elliptic_curves_t;

/*!
 * \enum Public key coordinates compression mode
 */
typedef enum ecc_compressed_mode_ {
  compressed_y_0, /*!< The last significant bit of Y-coodinate ended with 0 */
  compressed_y_1  /*!< The last significant bit of Y-coodinate ended with 1 */
} ecc_compressed_mode_t;

/*!
 * \enum Supported encryption algorithem
 */
typedef enum ecc_encryption_algorithm_ {
  aes_128_ccm,
  aes_256_ccm,
  aes_128_gcm,
  aes_256_gcm
} encryption_algorithm_t;

/*!
 * \struct ITS security context to be used in functions
 * \brief This data structure contains all the infomation required to achieve security computation such signature, ciphering...
 */
typedef struct lib_its_security_context_ {
  ecc_elliptic_curves_t  elliptic_curve;       /*! The ellicptic curve to be used */
  EC_KEY*                ec_key;               /*!< EC_KEY reference */
  EC_GROUP*              ec_group;             /*!< EC_GROUP reference */
  BN_CTX*                bn_ctx;               /*!< Pre-alocated memory used to increase OpenSSL processing */
  size_t                 key_length;           /*!< private/public keys length */
  uint8_t*               private_key;          /*!< Private key */
  uint8_t*               public_key_x;         /*!< Public key Y-coodinate */
  uint8_t*               public_key_y;         /*!< Public key Y-coodinate */
  uint8_t*               public_key_c;         /*!< Compressed Public key */
  ecc_compressed_mode_t  compressed_mode;      /*!< Compression mode */

  encryption_algorithm_t encryption_algorithm; /* Encryption algorithm currently used */
  uint8_t*               secret_key;
  uint8_t*               sym_key;
  uint8_t*               enc_sym_key;
  uint8_t*               tag;
  uint8_t*               nonce;
  size_t                 secret_key_length;
  size_t                 sym_key_length;
  size_t                 nonce_length;
  size_t                 tag_length;
} lib_its_security_context_t;

/**
 * \fn int32_t initialize(const ecc_elliptic_curves_t p_elliptic_curve, lib_its_security_context_t** p_lib_its_security_context);
 * \brief Initialize the ITS security context according to the specified elliptic curve. This function shall be called before any othe lib_its_security function.
 * \param[in] p_elliptic_curve The elliptic curve to be used
 * \param[out] p_lib_its_security_context The internl context (To be released using uninitialize function)
 * \return 0 on success,-1 otherwise
 */
int32_t initialize(const ecc_elliptic_curves_t p_elliptic_curve, lib_its_security_context_t** p_lib_its_security_context);

/**
 * \fn int32_t uninitialize(lib_its_security_context_t** p_lib_its_security_context);
 * \brief Release resources allocated by initialize fiunction
 * \param[in/out] p_lib_its_security_context The internl context
 * \return 0 on success,-1 otherwise
 */
int32_t uninitialize(lib_its_security_context_t** p_lib_its_security_context);

/**
 * \fn int32_t hash_with_sha256(const uint8_t* p_to_be_hashed_data,const size_t p_to_be_hashed_data_length,uint8_t** p_hashed_data);
 * \brief Produces a 256-bit (32-bytes) hash value
 * \param[in] p_to_be_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_hashed_data_length The length of the data to be hashed
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \return 0 on success,-1 otherwise
 */
int32_t hash_with_sha256(const uint8_t* p_to_be_hashed_data, const size_t p_to_be_hashed_data_length, uint8_t** p_hashed_data);
/**
 * \fn int32_t hash_with_sha384(const uint8_t* p_to_be_hashed_data,const size_t p_to_be_hashed_data_length,uint8_t** p_hashed_data);
 * \brief Produces a 384-bit (48-bytes) hash value
 * \param[in] p_to_be_hashed_data Data to be used to calculate the hash value
 * \param[in] p_to_be_hashed_data_length The length of the data to be hashed
 * \param[in] p_hashed_data The data to be used to calculate the hash value
 * \return 0 on success,-1 otherwise
 */
int32_t hash_with_sha384(const uint8_t* p_to_be_hashed_data, const size_t p_to_be_hashed_data_length, uint8_t** p_hashed_data);

/**
 * \fn int32_t hmac_sha256(const uint8_t* p_secret_key,const size p_secret_key_length,const OCTETSTRING& p_message,const size p_message_length, uint8_t** p_hmac);
 * \brief Generate a HMAC-SHA256 value based on the provided secret key
 * \param[in] p_secret_key The secret key used for the HMAC calculation
 * \param[in] p_message The message
 * \param[out] p_hmac The HMAC with SHA256 of the message resized to 16-bytes (To be released after use)
 * \return 0 on success,-1 otherwise
 */
int32_t hmac_sha256(const uint8_t* p_secret_key, const size_t p_secret_key_length, const uint8_t* p_message, const size_t p_message_length, uint8_t** p_hmac);

/**
 * \fn int32_t sign_with_ecdsa_nistp256_with_sha256(lib_its_security_context_t* p_lib_its_security_context, const uint8_t* p_to_be_signed_secured_message,const size_t p_to_be_signed_secured_message_length,const uint8_t* p_certificate_issuer,const uint8_t* p_private_key,uint8_t** p_signature);
 * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_signed_secured_message The data to be signed
 * \param[in] p_certificate_issuer The whole-hash issuer certificate or int2oct(0,32) in case of self signed certificate
 * \param[in] p_private_key The private key
 * \param[out] p_signature The signature of the data to be signed (To be released after use)
 * \return The signature value
 */
int32_t sign_with_ecdsa_nistp256_with_sha256(
                                             lib_its_security_context_t* p_lib_its_security_context,
                                             const uint8_t* p_to_be_signed_secured_message,
                                             const size_t p_to_be_signed_secured_message_length,
                                             const uint8_t* p_certificate_issuer,
                                             const uint8_t* p_private_key,
                                             uint8_t** p_signature
                                             );

/**
 * \fn int32_t sign_with_ecdsa_brainpoolp256r1_with_sha256(lib_its_security_context_t* p_lib_its_security_context, const uint8_t* p_to_be_signed_secured_message,const size_t p_to_be_signed_secured_message_length,const uint8_t* p_certificate_issuer,const uint8_t* p_private_key,uint8_t** p_signature);
 * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_signed_secured_message The data to be signed
 * \param[in] p_certificate_issuer The whole-hash issuer certificate or int2oct(0,32) in case of self signed certificate
 * \param[in] p_private_key The private key
 * \param[out] p_signature The signature of the data to be signed (To be released after use)
 * \return The signature value
 */
int32_t sign_with_ecdsa_brainpoolp256r1_with_sha256(
                                                    lib_its_security_context_t* p_lib_its_security_context,
                                                    const uint8_t* p_to_be_signed_secured_message,
                                                    const size_t p_to_be_signed_secured_message_length,
                                                    const uint8_t* p_certificate_issuer,
                                                    const uint8_t* p_private_key,
                                                    uint8_t** p_signature
                                                    );

/**
 * \fn int32_t sign_with_ecdsa_brainpoolp384r1_with_sha384(lib_its_security_context_t* p_lib_its_security_context, const uint8_t* p_to_be_signed_secured_message,const size_t p_to_be_signed_secured_message_length,const uint8_t* p_certificate_issuer,const uint8_t* p_private_key,uint8_t** p_signature);
 * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_signed_secured_message The data to be signed
 * \param[in] p_certificate_issuer The whole-hash issuer certificate or int2oct(0,32) in case of self signed certificate
 * \param[in] p_private_key The private key
 * \param[out] p_signature The signature of the data to be signed (To be released after use)
 * \return 0 on success,-1 otherwise
 */
int32_t sign_with_ecdsa_brainpoolp384r1_with_sha384(
                                                    lib_its_security_context_t* p_lib_its_security_context,
                                                    const uint8_t* p_to_be_signed_secured_message,
                                                    const size_t p_to_be_signed_secured_message_length,
                                                    const uint8_t* p_certificate_issuer,
                                                    const uint8_t* p_private_key,
                                                    uint8_t** p_signature
                                                    );

/**
 * \fn int32_t verify_with_ecdsa_nistp256_with_sha256(lib_its_security_context_t* p_lib_its_security_context, const uint8_t* p_to_be_verified_data,const size_t p_to_be_verified_data_length,const uint8_t* p_certificate_issuer,const uint8_t* p_signature,const uint8_t* p_ecdsa_nistp256_publicKey_compressed, const ecc_compressed_mode_t p_compressed_mode);
 * \brief Verify the signature of the specified data based on standard IEEE 1609.2
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_verified_data The data to be verified
 * \param[in] p_certificate_issuer The whole-hash issuer certificate or int2oct(0,32) in case of self signed certificate
 * \param[in] p_signature The signature
 * \param[in] p_ecdsa_nistp256_publicKey_compressed The compressed public key (x coordinate only)
 * \return 0 on success,-1 otherwise
 */
int32_t verify_with_ecdsa_nistp256_with_sha256(
                                               lib_its_security_context_t* p_lib_its_security_context,
                                               const uint8_t* p_to_be_verified_data,
                                               const size_t p_to_be_verified_data_length,
                                               const uint8_t* p_certificate_issuer,
                                               const uint8_t* p_signature,
                                               const uint8_t* p_ecdsa_nistp256_publicKey_compressed,
                                               const ecc_compressed_mode_t p_compressed_mode
                                               );

/**
 * \fn int32_t verify_with_ecdsa_nistp256_with_sha256_raw(lib_its_security_context_t* p_lib_its_security_context, const uint8_t* p_to_be_verified_data,const size_t p_to_be_verified_data_length,const uint8_t* p_certificate_issuer,const uint8_t* p_signature,const uint8_t* p_ecdsa_nistp256_publicKey_compressed, const ecc_compressed_mode_t p_compressed_mode));
 * \brief Verify the signature of the specified data based on raw data
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_verified_data The data to be verified
 * \param[in] p_signature The signature
 * \param[in] p_ecdsa_nistp256_publicKey_compressed The compressed public key (x coordinate only)
 * \return 0 on success,-1 otherwise
 */
int32_t verify_with_ecdsa_nistp256_with_sha256_raw(
                                                   lib_its_security_context_t* p_lib_its_security_context,
                                                   const uint8_t* p_to_be_verified_data,
                                                   const size_t p_to_be_verified_data_length,
                                                   const uint8_t* p_signature,
                                                   const uint8_t* p_ecdsa_nistp256_publicKey_compressed,
                                                   const ecc_compressed_mode_t p_compressed_mode
                                                   );

/**
 * \fn int32_t verify_with_ecdsa_brainpoolp256r1_with_sha256(lib_its_security_context_t* p_lib_its_security_context, const uint8_t* p_to_be_verified_data,const size_t p_to_be_verified_data_length,const uint8_t* p_certificate_issuer,const uint8_t* p_signature,const uint8_t* p_ecdsa_nistp256_publicKey_compressed, const ecc_compressed_mode_t p_compressed_mode);
 * \brief Verify the signature of the specified data based on standard IEEE 1609.2
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_verified_data The data to be verified
 * \param[in] p_certificate_issuer The whole-hash issuer certificate or int2oct(0,32) in case of self signed certificate
 * \param[in] p_signature The signature
 * \param[in] p_ecdsaBrainpoolp256PublicKeyCompressed The compressed public key (x coordinate only)
 * \return 0 on success,-1 otherwise
 */
int32_t verify_with_ecdsa_brainpoolp256r1_with_sha256(
                                                      lib_its_security_context_t* p_lib_its_security_context,
                                                      const uint8_t* p_to_be_verified_data,
                                                      const size_t p_to_be_verified_data_length,
                                                      const uint8_t* p_certificate_issuer,
                                                      const uint8_t* p_signature,
                                                      const uint8_t* p_ecdsaBrainpoolp256PublicKeyCompressed,
                                                      const ecc_compressed_mode_t p_compressed_mode
                                                      );

/**
 * \fn int32_t verify_with_ecdsa_brainpoolp384r1_with_sha384(lib_its_security_context_t* p_lib_its_security_context, const uint8_t* p_to_be_verified_data,const size_t p_to_be_verified_data_length,const uint8_t* p_certificate_issuer,const uint8_t* p_signature,const uint8_t* p_ecdsa_nistp256_publicKey_compressed, const ecc_compressed_mode_t p_compressed_mode);
 * \brief Verify the signature of the specified data based on standard IEEE 1609.2
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_verified_data The data to be verified
 * \param[in] p_certificate_issuer The whole-hash issuer certificate or int2oct(0,32) in case of self signed certificate
 * \param[in] p_signature The signature
 * \param[in] p_ecdsaBrainpoolp384PublicKeyCompressed The compressed public key (x coordinate only)
 * \return 0 on success,-1 otherwise
 */
int32_t verify_with_ecdsa_brainpoolp384r1_with_sha384(
                                                      lib_its_security_context_t* p_lib_its_security_context,
                                                      const uint8_t* p_to_be_verified_data,
                                                      const size_t p_to_be_verified_data_length,
                                                      const uint8_t* p_certificate_issuer,
                                                      const uint8_t* p_signature,
                                                      const uint8_t* p_ecdsaBrainpoolp384PublicKeyCompressed,
                                                      const ecc_compressed_mode_t p_compressed_mode
                                                      );

/**
 * \brief Encrypt the message using ECIES algorithm to encrypt AES 128 CCM symmetric key,as defined in IEEE Std 1609.2-2017
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_to_be_encrypted_secured_message The message to be encrypted
 * \param[in] p_recipients_public_key_compressed The Recipient's compressed public key
 * \param[in] p_compressed_mode The compressed mode,0 if the latest bit of Y-coordinate is 0,1 otherwise
 * \param[out] p_public_ephemeral_key_compressed The public ephemeral compressed key (To be released after use)
 * \param[out] p_ephemeral_compressed_mode The compressed mode,0 if the latest bit of Y-coordinate is 0,1 otherwise
 * \param[out] p_encrypted_sym_key The encrypted AES 128 symmetric key (To be released after use)
 * \param[out] p_authentication_vector The tag of the encrypted AES 128 symmetric key (To be released after use)
 * \param[out] p_nonce The nonce vector (To be released after use)
 uint8_t** p_encrypted_secured_message,
 size_t* p_encrypted_secured_message_length,
 * \return 0 on success,-1 otherwise
 * \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
 */
int32_t encrypt_with_ecies_nistp256_with_sha256(
                                                lib_its_security_context_t* p_lib_its_security_context,
                                                const uint8_t* p_to_be_encrypted_secured_message,
                                                const size_t p_to_be_encrypted_secured_message_length,
                                                const uint8_t* p_recipients_public_key_compressed,
                                                const ecc_compressed_mode_t p_compressed_mode,
                                                const uint8_t* p_salt,
                                                const size_t p_salt_length,
                                                uint8_t** p_public_ephemeral_key_compressed,
                                                ecc_compressed_mode_t* p_ephemeral_compressed_mode,
                                                uint8_t** p_aes_sym_key,
                                                uint8_t** p_encrypted_sym_key,
                                                uint8_t** p_authentication_vector,
                                                uint8_t** p_nonce,
                                                uint8_t** p_encrypted_secured_message,
                                                size_t* p_encrypted_secured_message_length
                                                );

/**
 * \brief Decrypt the message using ECIES algorithm to decrypt AES 128 CCM symmetric key,as defined in IEEE Std 1609.2-2017
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[in] p_encrypted_secured_message The encrypted message
 * \param[in] p_private_enc_key The private encryption key
 * \param[in] p_public_ephemeral_key_compressed The public ephemeral compressed key
 * \param[in] p_ephemeral_compressed_mode The compressed mode,0 if the latest bit of Y-coordinate is 0,1 otherwise
 * \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 0 on success,-1 otherwise
 * \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
 */
int32_t decrypt_with_ecies_nistp256_with_sha256(
                                                lib_its_security_context_t* p_lib_its_security_context,
                                                const uint8_t* p_encrypted_secured_message,
                                                const size_t p_encrypted_secured_message_length,
                                                const uint8_t* p_private_enc_key,
                                                const uint8_t* p_public_ephemeral_key_compressed,
                                                const ecc_compressed_mode_t p_ephemeral_compressed_mode,
                                                const uint8_t* p_encrypted_sym_key,
                                                const uint8_t* p_authentication_vector,
                                                const uint8_t* p_nonce,
                                                const uint8_t* p_salt,
                                                const size_t p_salt_length,
                                                uint8_t** p_aes_sym_enc_key,
                                                uint8_t** p_plain_text_message,
                                                size_t* p_plain_text_message_length
                                                );

int32_t encrypt_with_ecies_brainpoolp256r1_with_sha256(
                                                       lib_its_security_context_t* p_lib_its_security_context,
                                                       const uint8_t* p_to_be_encrypted_secured_message,
                                                       const size_t p_to_be_encrypted_secured_message_length,
                                                       const uint8_t* p_recipients_public_key_compressed,
                                                       const ecc_compressed_mode_t p_compressed_mode,
                                                       const uint8_t* p_salt,
                                                       const size_t p_salt_length,
                                                       uint8_t** p_public_ephemeral_key_compressed,
                                                       ecc_compressed_mode_t* p_ephemeral_compressed_mode,
                                                       uint8_t** p_aes_sym_key,
                                                       uint8_t** p_encrypted_sym_key,
                                                       uint8_t** p_authentication_vector,
                                                       uint8_t** p_nonce,
                                                       uint8_t** p_encrypted_secured_message,
                                                       size_t* p_encrypted_secured_message_length
                                                       );

int32_t decrypt_with_ecies_brainpoolp256r1_with_sha256(
                                                       lib_its_security_context_t* p_lib_its_security_context,
                                                       const uint8_t* p_encrypted_secured_message,
                                                       const size_t p_encrypted_secured_message_length,
                                                       const uint8_t* p_private_enc_key,
                                                       const uint8_t* p_public_ephemeral_key_compressed,
                                                       const ecc_compressed_mode_t p_ephemeral_compressed_mode,
                                                       const uint8_t* p_encrypted_sym_key,
                                                       const uint8_t* p_authentication_vector,
                                                       const uint8_t* p_nonce,
                                                       const uint8_t* p_salt,
                                                       const size_t p_salt_length,
                                                       uint8_t** p_aes_sym_enc_key,
                                                       uint8_t** p_plain_text_message,
                                                       size_t* p_plain_text_message_length
                                                       );

/**
 * \fn int32_t generate_key_pair(lib_its_security_context_t* p_lib_its_security_context, uint8_t** p_private_key,uint8_t** p_public_key_x,uint8_t** p_public_key_y,uint8_t** p_public_key_compressed, ecc_compressed_mode_t* p_compressed_mode);
 * \brief    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
 * \param[in/out] p_hashed_data The data to be used to calculate the hash value
 * \param[out] p_private_key    The new private key value (To be released after use)
 * \param[out] p_public_key_x    The new public key value (x coordinate) (To be released after use)
 * \param[out] p_public_key_x    The new public key value (y coordinate) (To be released after use)
 * \return 0 on success,-1 otherwise
 */
int32_t generate_key_pair(
                          lib_its_security_context_t* p_lib_its_security_context,
                          uint8_t** p_private_key,
                          uint8_t** p_public_key_x,
                          uint8_t** p_public_key_y,
                          uint8_t** p_public_key_compressed,
                          ecc_compressed_mode_t* p_compressed_mode
                          );