Loading ccsrc/Externals/LibItsSecurity_externals.cc +109 −49 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,8 @@ #include "sha256.hh" #include "sha256.hh" #include "sha384.hh" #include "sha384.hh" #include "hmac.hh" #include "security_ecc.hh" #include "security_ecc.hh" #include "security_services.hh" #include "security_services.hh" Loading Loading @@ -249,71 +251,123 @@ namespace LibItsSecurity__Functions return FALSE; return FALSE; } } OCTETSTRING fx__test__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m) { loggers::get_instance().log(">>> fx__test__hmac__sha256"); hmac h(hash_algorithms::sha_256); // TODO Use ec_encryption_algorithm std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k)); std::vector<unsigned char> m(static_cast<const unsigned char *>(p__m), p__m.lengthof() + static_cast<const unsigned char *>(p__m)); std::vector<unsigned char> t; if (h.generate(m, k, t) == -1) { loggers::get_instance().warning("fx__test__hmac__sha256: Failed to generate HMAC"); return OCTETSTRING(); } OCTETSTRING os(t.size(), t.data()); loggers::get_instance().log_to_hexa("fx__test__hmac__sha256: HMAC: ", os); return os; } OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__peerPublicKeyX, const OCTETSTRING& p__peerPublicKeyY, OCTETSTRING& p__publicEncKeyX, OCTETSTRING& p__publicEncKeyY, OCTETSTRING& p__ephKey, OCTETSTRING& p__tag, OCTETSTRING& p__nonce) { OCTETSTRING fx__test__encrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt) { loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: ", p__toBeEncryptedSecuredMessage); loggers::get_instance().log(">>> fx__test__encrypt__aes__128__ccm__test"); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: ", p__peerPublicKeyX); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: ", p__publicEncKeyY); // Encrypt message using AES-128 CCM security_ecc ec(ec_elliptic_curves::nist_p_256); security_ecc ec(ec_elliptic_curves::nist_p_256); std::vector<unsigned char> message(static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage), p__toBeEncryptedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage)); std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k)); std::vector<unsigned char> n(static_cast<const unsigned char *>(p__n), p__n.lengthof() + static_cast<const unsigned char *>(p__n)); std::vector<unsigned char> pt(static_cast<const unsigned char *>(p__pt), p__pt.lengthof() + static_cast<const unsigned char *>(p__pt)); std::vector<unsigned char> enc_message; std::vector<unsigned char> enc_message; if (ec.encrypt(encryption_algotithm::aes_128_ccm, message, enc_message) == -1) { if (ec.encrypt(encryption_algotithm::aes_128_ccm, k, n, pt, enc_message) == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message"); loggers::get_instance().warning("fx__test__encrypt__aes__128__ccm__test: Failed to encrypt message"); return OCTETSTRING(); return OCTETSTRING(); } } OCTETSTRING os(enc_message.size(), enc_message.data()); OCTETSTRING os(enc_message.size(), enc_message.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc message: ", os); os = os + OCTETSTRING(ec.tag().size(), ec.tag().data()); p__nonce = OCTETSTRING(ec.nonce().size(), ec.nonce().data()); loggers::get_instance().log_to_hexa("fx__test__encrypt__aes__128__ccm__test: encrypted message: ", os); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce); p__tag = OCTETSTRING(ec.tag().size(), ec.tag().data()); return os; loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__tag: ", p__tag); // Encrypt the symmetric key OCTETSTRING encSymKey = OCTETSTRING(ec.nonce().size(), ec.symmetric_encryption_key().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__encSymKey: ", encSymKey); // 1. Create new instance of ECC security_ecc ec_ecies(ec_elliptic_curves::nist_p_256); // 2. Generate (Private,Public) keys ec_ecies.generate(); // Generate ephemeral key and derive it std::vector<unsigned char> peer_public_key_x(static_cast<const unsigned char *>(p__peerPublicKeyX), p__peerPublicKeyX.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyX)); std::vector<unsigned char> peer_public_key_y(static_cast<const unsigned char *>(p__publicEncKeyY), p__publicEncKeyY.lengthof() + static_cast<const unsigned char *>(p__publicEncKeyY)); if (ec_ecies.generate_and_derive_ephemeral_key( peer_public_key_x, peer_public_key_y ) != 0) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate and derive sender's ephemeral key"); return OCTETSTRING(); } } // 3. Encrypt the symmetric encryption key using existing nonce and symmetric encryption key std::vector<unsigned char> enc_eph_key; OCTETSTRING fx__test__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct) { if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec_ecies.ephemeral_key(), ec.nonce(), ec.symmetric_encryption_key(), enc_eph_key) == -1) { loggers::get_instance().log(">>> fx__test__decrypt__aes__128__ccm__test"); loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message"); security_ecc ec(ec_elliptic_curves::nist_p_256); std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k)); std::vector<unsigned char> n(static_cast<const unsigned char *>(p__n), p__n.lengthof() + static_cast<const unsigned char *>(p__n)); std::vector<unsigned char> ct(static_cast<const unsigned char *>(p__ct), p__ct.lengthof() + static_cast<const unsigned char *>(p__ct)); // Extract the tag std::vector<unsigned char> tag(16, 0x00); std::copy(ct.end() - tag.size(), ct.end(), tag.begin()); loggers::get_instance().log_to_hexa("fx__test__decrypt__aes__128__ccm__test: tag: ", tag.data(), tag.size()); // Remove the tag from the end of the encrypted message ct.resize(ct.size() - tag.size()); std::vector<unsigned char> message; if (ec.decrypt(encryption_algotithm::aes_128_ccm, k, n, tag, ct, message) == -1) { loggers::get_instance().warning("fx__test__decrypt__aes__128__ccm__test: Failed to decrypt message"); return OCTETSTRING(); return OCTETSTRING(); } } p__ephKey = OCTETSTRING(enc_eph_key.size(), enc_eph_key.data()); OCTETSTRING os(message.size(), message.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__ephKey: ", ec.ephemeral_key().data(), ec.ephemeral_key().size()); loggers::get_instance().log_to_hexa("fx__test__decrypt__aes__128__ccm__test: decrypted message: ", os); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Encrypted p__ephKey: ", p__ephKey); p__publicEncKeyX = OCTETSTRING(ec.encryption_key_x().size(), ec_ecies.encryption_key_x().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__publicEncKeyX: ", p__publicEncKeyX); p__publicEncKeyY = OCTETSTRING(ec.encryption_key_y().size(), ec_ecies.encryption_key_y().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__publicEncKeyY: ", p__publicEncKeyY); return os; return os; } } OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__publicKeyX, const OCTETSTRING& p__publicKeyY, const OCTETSTRING& p__nonce, const OCTETSTRING& p__tag) { OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__peerPublicKeyX, const OCTETSTRING& p__peerPublicKeyY, OCTETSTRING& p__publicEncKeyX, OCTETSTRING& p__publicEncKeyY, OCTETSTRING& p__hmac, OCTETSTRING& p__authentication_vector, OCTETSTRING& p__nonce) { loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__toBeEncryptedSecuredMessage); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__peerPublicKeyX: ", p__peerPublicKeyX); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__peerPublicKeyY: ", p__peerPublicKeyY); // 1. Generate new Private/Public key security_ecc ec(ec_elliptic_curves::nist_p_256); if (ec.generate() == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate ephemeral keys"); return OCTETSTRING(); } // 2. Generate and derive shared secret std::vector<unsigned char> peer_public_key_x(static_cast<const unsigned char *>(p__peerPublicKeyX), p__peerPublicKeyX.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyX)); std::vector<unsigned char> peer_public_key_y(static_cast<const unsigned char *>(p__peerPublicKeyY), p__peerPublicKeyY.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyY)); std::vector<unsigned char> authentication_vector; // FIXME Check what to do with the authentication_vector if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, peer_public_key_x, peer_public_key_y, authentication_vector) == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate and derive secret key"); return OCTETSTRING(); } p__authentication_vector = OCTETSTRING(authentication_vector.size(), authentication_vector.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__authentication_vector: ", p__authentication_vector); // 3. Retrieve AES 128 parameters p__nonce = OCTETSTRING(ec.nonce().size(), ec.nonce().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce); OCTETSTRING enc_symm_key = OCTETSTRING(ec.symmetric_encryption_key().size(), ec.symmetric_encryption_key().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc_symm_key: ", enc_symm_key); // 4. Encrypt the data using AES-128 CCM std::vector<unsigned char> message(static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage), p__toBeEncryptedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage)); std::vector<unsigned char> enc_message; if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), message, enc_message) == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message"); return OCTETSTRING(); } enc_message.insert(enc_message.end(), std::make_move_iterator(ec.tag().begin()), std::make_move_iterator(ec.tag().end())); OCTETSTRING os(enc_message.size(), enc_message.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc message||Tag: ", os); OCTETSTRING os; // 5. Setup the output parameters p__hmac = OCTETSTRING(ec.enc_hmac().size(), ec.enc_hmac().data()); os = OCTETSTRING(); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Hmac: ", p__hmac); p__publicEncKeyX = OCTETSTRING(ec.public_key_x().size(), ec.public_key_x().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key X: ", p__publicEncKeyX); p__publicEncKeyY = OCTETSTRING(ec.public_key_y().size(), ec.public_key_y().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key Y: ", p__publicEncKeyY); return os; return os; } } OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__publicKeyX, const OCTETSTRING& p__publicKeyY, const OCTETSTRING& p__nonce, const OCTETSTRING& p__authentication_vector) { loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage); return OCTETSTRING(); } /** /** * @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm. * @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm. * This function should not be used by the ATS * This function should not be used by the ATS Loading Loading @@ -574,6 +628,12 @@ namespace LibItsSecurity__Functions const CHARSTRING& p__certificateId, const CHARSTRING& p__certificateId, OCTETSTRING& p__encryptingPrivateKey OCTETSTRING& p__encryptingPrivateKey ) { ) { loggers::get_instance().log(">>> fx__readSigningKey: '%s'", static_cast<const char*>(p__certificateId)); if (security_services::get_instance().read_private_enc_key(p__certificateId, p__encryptingPrivateKey) == -1) { return FALSE; } return TRUE; return TRUE; } } Loading ccsrc/Protocols/Security/hmac.hh +12 −8 Original line number Original line Diff line number Diff line Loading @@ -46,9 +46,9 @@ public: /*! /*! * \inline * \inline * \fn int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac); * \fn int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac); * \brief Receive bytes formated data from the lower layers * \brief Generate the HMAC of data using a secret key * \param[in] p_buffer The data used to generate the HMAC * \Param[in] p_buffer The data tobe hashed * \param[in] p_secret_key The secret key to used to generate the HMAC * \param[in] p_secret_key The secret key to be used to generate the HMAC * \param[out] p_hmac The HMAC value based of the provided data * \param[out] p_hmac The HMAC value based of the provided data * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise */ */ Loading @@ -64,10 +64,10 @@ public: /*! /*! * \inline * \inline * \fn int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac); * \fn int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac); * \brief Receive bytes formated data from the lower layers * \brief Generate the HMAC of data using a secret key * \param[in] p_buffer The data used to generate the HMAC * \param[in] p_buffer The data to be hashed * \param[in] p_buffer_length The size of the data * \param[in] p_buffer_length The size of the data * \param[in] p_secret_key The secret key to used to generate the HMAC * \param[in] p_secret_key The secret key to be used to generate the HMAC * \param[in] p_secret_key_length The size of the secret key * \param[in] p_secret_key_length The size of the secret key * \param[out] p_hmac The HMAC value based of the provided data * \param[out] p_hmac The HMAC value based of the provided data * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise Loading @@ -78,11 +78,10 @@ public: return -1; return -1; } } p_hmac.resize(EVP_MAX_MD_SIZE); if (_hash_algorithms == hash_algorithms::sha_256) { if (_hash_algorithms == hash_algorithms::sha_256) { p_hmac.resize(64); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha256(), NULL); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha256(), NULL); } else if (_hash_algorithms == hash_algorithms::sha_384) { } else if (_hash_algorithms == hash_algorithms::sha_384) { p_hmac.resize(128); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha384(), NULL); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha384(), NULL); } else { // TODO To be continued } else { // TODO To be continued return -1; return -1; Loading @@ -91,6 +90,11 @@ public: ::HMAC_Update(&_ctx, p_buffer, p_buffer_length); ::HMAC_Update(&_ctx, p_buffer, p_buffer_length); unsigned int length = p_hmac.size(); unsigned int length = p_hmac.size(); ::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()), &length); ::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()), &length); // Resize the hmac if (_hash_algorithms == hash_algorithms::sha_256) { p_hmac.resize(16); } // FIXME Check length for the other hash algorithm return 0; return 0; }; }; }; // End of class hmac }; // End of class hmac ccsrc/Protocols/Security/security_ecc.cc +119 −105 File changed.Preview size limit exceeded, changes collapsed. Show changes ccsrc/Protocols/Security/security_ecc.hh +48 −23 Original line number Original line Diff line number Diff line Loading @@ -49,10 +49,11 @@ class security_ecc { std::vector<unsigned char> _pri_key; /*!< Private key storage */ std::vector<unsigned char> _pri_key; /*!< Private key storage */ std::vector<unsigned char> _pub_key_x; /*!< Public key X-coordinate storage */ std::vector<unsigned char> _pub_key_x; /*!< Public key X-coordinate storage */ std::vector<unsigned char> _pub_key_y; /*!< Public key Y-coordinate storage */ std::vector<unsigned char> _pub_key_y; /*!< Public key Y-coordinate storage */ std::vector<unsigned char> _eph_key; /*!< Ephemeral key generated by ECIES encryption method */ std::vector<unsigned char> _secret_key; /*!< Shared secret key generated by ECIES encryption method */ std::vector<unsigned char> _enc_key_x; /*!< Public encryption key X-coordinate storage */ std::vector<unsigned char> _hmac; /*!< HMAC key resulting of the derivation of the shared secret key */ std::vector<unsigned char> _enc_key_y; /*!< Public encryption key Y-coordinate storage */ std::vector<unsigned char> _enc_key_x; /*!< Ephemeral public key X-coordinate storage */ std::vector<unsigned char> _sym_key; /*!< Symmetric encryption key generated by encryption method */ std::vector<unsigned char> _enc_key_y; /*!< Ephemeral public key Y-coordinate storage */ std::vector<unsigned char> _sym_key; /*!< AES symmetric encryption key generated by encryption method */ std::vector<unsigned char> _nonce; /*!< Initial Vector generated by encryption method */ std::vector<unsigned char> _nonce; /*!< Initial Vector generated by encryption method */ std::vector<unsigned char> _tag; /*!< Tag vector generated by encryption method */ std::vector<unsigned char> _tag; /*!< Tag vector generated by encryption method */ Loading Loading @@ -107,9 +108,40 @@ public: //! \publicsection */ */ int sign_verif(const std::vector<unsigned char>& p_data, const std::vector<unsigned char>& p_signature); int sign_verif(const std::vector<unsigned char>& p_data, const std::vector<unsigned char>& p_signature); /*! * \fn int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector); * \brief Generate a shared secret key and derive it using KDF2 algorithm. * This method shall be used by the sender. Fresh keys will be genrated for each cyphering operation * \param[in] p_enc_algorithm The encryption algorithm to be used * \param[in] p_peer_public_key_x The recipient public key X-coordinate * \param[in] p_peer_public_key_x The recipient public key Y-coordinate * \remark To get the secret key, uses \see secret_key method * \remark To get the generated symmetric encryption key, uses \see symmetric_encryption_key method * \remark To get the generated nonce vector, uses \see nonce method * \see encrypt methog to encrypt a message based of the generated symetric encryption key * \return 0 on success, -1 otherwise */ int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector); /*! * \fn int generate_and_derive_ephemeral_key(const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y); * \brief Generate a shared secret key and derive it using KDF2 algorithm. * \param[in] p_enc_algorithm The encryption algorithm to be used * \param[in] p_enc_key The private encryption key associated to the public encryption key * \param[in] p_peer_public_key_x The recipient public key X-coordinate * \param[in] p_peer_public_key_x The recipient public key Y-coordinate * \remark To get the secret key, uses \see secret_key method * \remark To get the generated symmetric encryption key, uses \see symmetric_encryption_key method * \remark To get the generated nonce vector, uses \see nonce method * \return 0 on success, -1 otherwise */ int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_private_enc_key, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector) { return -1; }; /*! /*! * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \brief Encryption using the specified algorithm. * \brief Encryption using the specified algorithm, the encryption parameters are generated automatically. * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_message The message to be encrypted * \param[in] p_message The message to be encrypted * \param[out] p_enc_message The encrypted message * \param[out] p_enc_message The encrypted message Loading @@ -121,7 +153,7 @@ public: //! \publicsection int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); /*! /*! * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \brief Encryption using the specified algorithm. * \brief Encryption using the specified algorithm. The encryption parameters are provided by the caller (e.g. ECIES encryption). * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_symmetric_key * \param[in] p_symmetric_key * \param[in] p_nonce * \param[in] p_nonce Loading @@ -146,32 +178,18 @@ public: //! \publicsection * \remark To get the generated tag, uses \see tag method * \remark To get the generated tag, uses \see tag method * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise */ */ int decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_key, 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 decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, 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); // TODO To be reorganised // TODO To be reorganised /*! * \fn int generate_and_derive_ephemeral_key(const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y); * \brief Generate a shared secret key and derive it using KDF2 algorithm. * \param[in] p_peer_public_key_x The recipient public key X-coordinate * \param[in] p_peer_public_key_x The recipient public key Y-coordinate * \remark To get the generated ephemeral key, uses \see ephemeral_key method * \remark To get the generated nonce vector, uses \see nonce method * \remark To get the generated tag, uses \see tag method * \return 0 on success, -1 otherwise */ int generate_and_derive_ephemeral_key(const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y); // 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 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); 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>& private_key() const { return _pri_key; }; inline const std::vector<unsigned char>& public_key_x() const { return _pub_key_x; }; inline const std::vector<unsigned char>& public_key_x() const { return _pub_key_x; }; inline const std::vector<unsigned char>& public_key_y() const { return _pub_key_y; }; inline const std::vector<unsigned char>& public_key_y() const { return _pub_key_y; }; inline const std::vector<unsigned char>& ephemeral_key() const { return _eph_key; }; inline const std::vector<unsigned char>& secret_key() const { return _secret_key; }; inline const std::vector<unsigned char>& encryption_key_x() const { return _enc_key_x; }; inline const std::vector<unsigned char>& encryption_key_x() const { return _enc_key_x; }; inline const std::vector<unsigned char>& encryption_key_y() const { return _enc_key_y; }; inline const std::vector<unsigned char>& encryption_key_y() const { return _enc_key_y; }; inline const std::vector<unsigned char>& enc_hmac() const { return _hmac; }; inline const std::vector<unsigned char>& symmetric_encryption_key() const { return _sym_key; }; inline const std::vector<unsigned char>& symmetric_encryption_key() const { return _sym_key; }; inline const std::vector<unsigned char>& nonce() const { return _nonce; }; inline const std::vector<unsigned char>& nonce() const { return _nonce; }; inline const std::vector<unsigned char>& tag() const { return _tag; }; inline const std::vector<unsigned char>& tag() const { return _tag; }; Loading @@ -195,4 +213,11 @@ private: //! \privatesection * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise */ */ int public_key_to_bin(std::vector<unsigned char>& p_bin_key); int public_key_to_bin(std::vector<unsigned char>& p_bin_key); /*int multiply_point_with_bn(const EC_POINT &a, const BIGNUM* b, EC_POINT **P); // R: XY-coordinate compressed, S: Share Secret int derive_s_from_private_key(BIGNUM *S, BIGNUM *R); // R: XY-coordinate compressed, S: Share Secret int derive_s_from_public_key(BIGNUM *S, BIGNUM *R);*/ }; // End of class security_ecc }; // End of class security_ecc ccsrc/Protocols/Security/security_services.cc +4 −0 Original line number Original line Diff line number Diff line Loading @@ -781,3 +781,7 @@ int security_services::read_certificate_from_digest(const OCTETSTRING& p_digest, int security_services::read_private_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_key) const { int security_services::read_private_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_key) const { return _security_db.get()->get_private_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_key); return _security_db.get()->get_private_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_key); } } int security_services::read_private_enc_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_enc_key) const { return _security_db.get()->get_private_enc_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_enc_key); } Loading
ccsrc/Externals/LibItsSecurity_externals.cc +109 −49 Original line number Original line Diff line number Diff line Loading @@ -2,6 +2,8 @@ #include "sha256.hh" #include "sha256.hh" #include "sha384.hh" #include "sha384.hh" #include "hmac.hh" #include "security_ecc.hh" #include "security_ecc.hh" #include "security_services.hh" #include "security_services.hh" Loading Loading @@ -249,71 +251,123 @@ namespace LibItsSecurity__Functions return FALSE; return FALSE; } } OCTETSTRING fx__test__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m) { loggers::get_instance().log(">>> fx__test__hmac__sha256"); hmac h(hash_algorithms::sha_256); // TODO Use ec_encryption_algorithm std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k)); std::vector<unsigned char> m(static_cast<const unsigned char *>(p__m), p__m.lengthof() + static_cast<const unsigned char *>(p__m)); std::vector<unsigned char> t; if (h.generate(m, k, t) == -1) { loggers::get_instance().warning("fx__test__hmac__sha256: Failed to generate HMAC"); return OCTETSTRING(); } OCTETSTRING os(t.size(), t.data()); loggers::get_instance().log_to_hexa("fx__test__hmac__sha256: HMAC: ", os); return os; } OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__peerPublicKeyX, const OCTETSTRING& p__peerPublicKeyY, OCTETSTRING& p__publicEncKeyX, OCTETSTRING& p__publicEncKeyY, OCTETSTRING& p__ephKey, OCTETSTRING& p__tag, OCTETSTRING& p__nonce) { OCTETSTRING fx__test__encrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt) { loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: ", p__toBeEncryptedSecuredMessage); loggers::get_instance().log(">>> fx__test__encrypt__aes__128__ccm__test"); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: ", p__peerPublicKeyX); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: ", p__publicEncKeyY); // Encrypt message using AES-128 CCM security_ecc ec(ec_elliptic_curves::nist_p_256); security_ecc ec(ec_elliptic_curves::nist_p_256); std::vector<unsigned char> message(static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage), p__toBeEncryptedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage)); std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k)); std::vector<unsigned char> n(static_cast<const unsigned char *>(p__n), p__n.lengthof() + static_cast<const unsigned char *>(p__n)); std::vector<unsigned char> pt(static_cast<const unsigned char *>(p__pt), p__pt.lengthof() + static_cast<const unsigned char *>(p__pt)); std::vector<unsigned char> enc_message; std::vector<unsigned char> enc_message; if (ec.encrypt(encryption_algotithm::aes_128_ccm, message, enc_message) == -1) { if (ec.encrypt(encryption_algotithm::aes_128_ccm, k, n, pt, enc_message) == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message"); loggers::get_instance().warning("fx__test__encrypt__aes__128__ccm__test: Failed to encrypt message"); return OCTETSTRING(); return OCTETSTRING(); } } OCTETSTRING os(enc_message.size(), enc_message.data()); OCTETSTRING os(enc_message.size(), enc_message.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc message: ", os); os = os + OCTETSTRING(ec.tag().size(), ec.tag().data()); p__nonce = OCTETSTRING(ec.nonce().size(), ec.nonce().data()); loggers::get_instance().log_to_hexa("fx__test__encrypt__aes__128__ccm__test: encrypted message: ", os); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce); p__tag = OCTETSTRING(ec.tag().size(), ec.tag().data()); return os; loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__tag: ", p__tag); // Encrypt the symmetric key OCTETSTRING encSymKey = OCTETSTRING(ec.nonce().size(), ec.symmetric_encryption_key().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__encSymKey: ", encSymKey); // 1. Create new instance of ECC security_ecc ec_ecies(ec_elliptic_curves::nist_p_256); // 2. Generate (Private,Public) keys ec_ecies.generate(); // Generate ephemeral key and derive it std::vector<unsigned char> peer_public_key_x(static_cast<const unsigned char *>(p__peerPublicKeyX), p__peerPublicKeyX.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyX)); std::vector<unsigned char> peer_public_key_y(static_cast<const unsigned char *>(p__publicEncKeyY), p__publicEncKeyY.lengthof() + static_cast<const unsigned char *>(p__publicEncKeyY)); if (ec_ecies.generate_and_derive_ephemeral_key( peer_public_key_x, peer_public_key_y ) != 0) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate and derive sender's ephemeral key"); return OCTETSTRING(); } } // 3. Encrypt the symmetric encryption key using existing nonce and symmetric encryption key std::vector<unsigned char> enc_eph_key; OCTETSTRING fx__test__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct) { if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec_ecies.ephemeral_key(), ec.nonce(), ec.symmetric_encryption_key(), enc_eph_key) == -1) { loggers::get_instance().log(">>> fx__test__decrypt__aes__128__ccm__test"); loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message"); security_ecc ec(ec_elliptic_curves::nist_p_256); std::vector<unsigned char> k(static_cast<const unsigned char *>(p__k), p__k.lengthof() + static_cast<const unsigned char *>(p__k)); std::vector<unsigned char> n(static_cast<const unsigned char *>(p__n), p__n.lengthof() + static_cast<const unsigned char *>(p__n)); std::vector<unsigned char> ct(static_cast<const unsigned char *>(p__ct), p__ct.lengthof() + static_cast<const unsigned char *>(p__ct)); // Extract the tag std::vector<unsigned char> tag(16, 0x00); std::copy(ct.end() - tag.size(), ct.end(), tag.begin()); loggers::get_instance().log_to_hexa("fx__test__decrypt__aes__128__ccm__test: tag: ", tag.data(), tag.size()); // Remove the tag from the end of the encrypted message ct.resize(ct.size() - tag.size()); std::vector<unsigned char> message; if (ec.decrypt(encryption_algotithm::aes_128_ccm, k, n, tag, ct, message) == -1) { loggers::get_instance().warning("fx__test__decrypt__aes__128__ccm__test: Failed to decrypt message"); return OCTETSTRING(); return OCTETSTRING(); } } p__ephKey = OCTETSTRING(enc_eph_key.size(), enc_eph_key.data()); OCTETSTRING os(message.size(), message.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__ephKey: ", ec.ephemeral_key().data(), ec.ephemeral_key().size()); loggers::get_instance().log_to_hexa("fx__test__decrypt__aes__128__ccm__test: decrypted message: ", os); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Encrypted p__ephKey: ", p__ephKey); p__publicEncKeyX = OCTETSTRING(ec.encryption_key_x().size(), ec_ecies.encryption_key_x().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__publicEncKeyX: ", p__publicEncKeyX); p__publicEncKeyY = OCTETSTRING(ec.encryption_key_y().size(), ec_ecies.encryption_key_y().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__publicEncKeyY: ", p__publicEncKeyY); return os; return os; } } OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__publicKeyX, const OCTETSTRING& p__publicKeyY, const OCTETSTRING& p__nonce, const OCTETSTRING& p__tag) { OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__peerPublicKeyX, const OCTETSTRING& p__peerPublicKeyY, OCTETSTRING& p__publicEncKeyX, OCTETSTRING& p__publicEncKeyY, OCTETSTRING& p__hmac, OCTETSTRING& p__authentication_vector, OCTETSTRING& p__nonce) { loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__toBeEncryptedSecuredMessage); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__peerPublicKeyX: ", p__peerPublicKeyX); loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__peerPublicKeyY: ", p__peerPublicKeyY); // 1. Generate new Private/Public key security_ecc ec(ec_elliptic_curves::nist_p_256); if (ec.generate() == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate ephemeral keys"); return OCTETSTRING(); } // 2. Generate and derive shared secret std::vector<unsigned char> peer_public_key_x(static_cast<const unsigned char *>(p__peerPublicKeyX), p__peerPublicKeyX.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyX)); std::vector<unsigned char> peer_public_key_y(static_cast<const unsigned char *>(p__peerPublicKeyY), p__peerPublicKeyY.lengthof() + static_cast<const unsigned char *>(p__peerPublicKeyY)); std::vector<unsigned char> authentication_vector; // FIXME Check what to do with the authentication_vector if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, peer_public_key_x, peer_public_key_y, authentication_vector) == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate and derive secret key"); return OCTETSTRING(); } p__authentication_vector = OCTETSTRING(authentication_vector.size(), authentication_vector.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__authentication_vector: ", p__authentication_vector); // 3. Retrieve AES 128 parameters p__nonce = OCTETSTRING(ec.nonce().size(), ec.nonce().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce); OCTETSTRING enc_symm_key = OCTETSTRING(ec.symmetric_encryption_key().size(), ec.symmetric_encryption_key().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc_symm_key: ", enc_symm_key); // 4. Encrypt the data using AES-128 CCM std::vector<unsigned char> message(static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage), p__toBeEncryptedSecuredMessage.lengthof() + static_cast<const unsigned char *>(p__toBeEncryptedSecuredMessage)); std::vector<unsigned char> enc_message; if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), message, enc_message) == -1) { loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message"); return OCTETSTRING(); } enc_message.insert(enc_message.end(), std::make_move_iterator(ec.tag().begin()), std::make_move_iterator(ec.tag().end())); OCTETSTRING os(enc_message.size(), enc_message.data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc message||Tag: ", os); OCTETSTRING os; // 5. Setup the output parameters p__hmac = OCTETSTRING(ec.enc_hmac().size(), ec.enc_hmac().data()); os = OCTETSTRING(); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Hmac: ", p__hmac); p__publicEncKeyX = OCTETSTRING(ec.public_key_x().size(), ec.public_key_x().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key X: ", p__publicEncKeyX); p__publicEncKeyY = OCTETSTRING(ec.public_key_y().size(), ec.public_key_y().data()); loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: Ephemeral public key Y: ", p__publicEncKeyY); return os; return os; } } OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__publicKeyX, const OCTETSTRING& p__publicKeyY, const OCTETSTRING& p__nonce, const OCTETSTRING& p__authentication_vector) { loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage); return OCTETSTRING(); } /** /** * @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm. * @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm. * This function should not be used by the ATS * This function should not be used by the ATS Loading Loading @@ -574,6 +628,12 @@ namespace LibItsSecurity__Functions const CHARSTRING& p__certificateId, const CHARSTRING& p__certificateId, OCTETSTRING& p__encryptingPrivateKey OCTETSTRING& p__encryptingPrivateKey ) { ) { loggers::get_instance().log(">>> fx__readSigningKey: '%s'", static_cast<const char*>(p__certificateId)); if (security_services::get_instance().read_private_enc_key(p__certificateId, p__encryptingPrivateKey) == -1) { return FALSE; } return TRUE; return TRUE; } } Loading
ccsrc/Protocols/Security/hmac.hh +12 −8 Original line number Original line Diff line number Diff line Loading @@ -46,9 +46,9 @@ public: /*! /*! * \inline * \inline * \fn int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac); * \fn int generate(const std::vector<unsigned char> p_buffer, const std::vector<unsigned char> p_secret_key, std::vector<unsigned char>& p_hmac); * \brief Receive bytes formated data from the lower layers * \brief Generate the HMAC of data using a secret key * \param[in] p_buffer The data used to generate the HMAC * \Param[in] p_buffer The data tobe hashed * \param[in] p_secret_key The secret key to used to generate the HMAC * \param[in] p_secret_key The secret key to be used to generate the HMAC * \param[out] p_hmac The HMAC value based of the provided data * \param[out] p_hmac The HMAC value based of the provided data * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise */ */ Loading @@ -64,10 +64,10 @@ public: /*! /*! * \inline * \inline * \fn int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac); * \fn int generate(const unsigned char *p_buffer, const size_t p_buffer_length, const unsigned char *p_secret_key, const size_t p_secret_key_length, std::vector<unsigned char>& p_hmac); * \brief Receive bytes formated data from the lower layers * \brief Generate the HMAC of data using a secret key * \param[in] p_buffer The data used to generate the HMAC * \param[in] p_buffer The data to be hashed * \param[in] p_buffer_length The size of the data * \param[in] p_buffer_length The size of the data * \param[in] p_secret_key The secret key to used to generate the HMAC * \param[in] p_secret_key The secret key to be used to generate the HMAC * \param[in] p_secret_key_length The size of the secret key * \param[in] p_secret_key_length The size of the secret key * \param[out] p_hmac The HMAC value based of the provided data * \param[out] p_hmac The HMAC value based of the provided data * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise Loading @@ -78,11 +78,10 @@ public: return -1; return -1; } } p_hmac.resize(EVP_MAX_MD_SIZE); if (_hash_algorithms == hash_algorithms::sha_256) { if (_hash_algorithms == hash_algorithms::sha_256) { p_hmac.resize(64); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha256(), NULL); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha256(), NULL); } else if (_hash_algorithms == hash_algorithms::sha_384) { } else if (_hash_algorithms == hash_algorithms::sha_384) { p_hmac.resize(128); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha384(), NULL); ::HMAC_Init_ex(&_ctx, (const void*)p_secret_key, (long unsigned int)p_secret_key_length, EVP_sha384(), NULL); } else { // TODO To be continued } else { // TODO To be continued return -1; return -1; Loading @@ -91,6 +90,11 @@ public: ::HMAC_Update(&_ctx, p_buffer, p_buffer_length); ::HMAC_Update(&_ctx, p_buffer, p_buffer_length); unsigned int length = p_hmac.size(); unsigned int length = p_hmac.size(); ::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()), &length); ::HMAC_Final(&_ctx, static_cast<unsigned char*>(p_hmac.data()), &length); // Resize the hmac if (_hash_algorithms == hash_algorithms::sha_256) { p_hmac.resize(16); } // FIXME Check length for the other hash algorithm return 0; return 0; }; }; }; // End of class hmac }; // End of class hmac
ccsrc/Protocols/Security/security_ecc.cc +119 −105 File changed.Preview size limit exceeded, changes collapsed. Show changes
ccsrc/Protocols/Security/security_ecc.hh +48 −23 Original line number Original line Diff line number Diff line Loading @@ -49,10 +49,11 @@ class security_ecc { std::vector<unsigned char> _pri_key; /*!< Private key storage */ std::vector<unsigned char> _pri_key; /*!< Private key storage */ std::vector<unsigned char> _pub_key_x; /*!< Public key X-coordinate storage */ std::vector<unsigned char> _pub_key_x; /*!< Public key X-coordinate storage */ std::vector<unsigned char> _pub_key_y; /*!< Public key Y-coordinate storage */ std::vector<unsigned char> _pub_key_y; /*!< Public key Y-coordinate storage */ std::vector<unsigned char> _eph_key; /*!< Ephemeral key generated by ECIES encryption method */ std::vector<unsigned char> _secret_key; /*!< Shared secret key generated by ECIES encryption method */ std::vector<unsigned char> _enc_key_x; /*!< Public encryption key X-coordinate storage */ std::vector<unsigned char> _hmac; /*!< HMAC key resulting of the derivation of the shared secret key */ std::vector<unsigned char> _enc_key_y; /*!< Public encryption key Y-coordinate storage */ std::vector<unsigned char> _enc_key_x; /*!< Ephemeral public key X-coordinate storage */ std::vector<unsigned char> _sym_key; /*!< Symmetric encryption key generated by encryption method */ std::vector<unsigned char> _enc_key_y; /*!< Ephemeral public key Y-coordinate storage */ std::vector<unsigned char> _sym_key; /*!< AES symmetric encryption key generated by encryption method */ std::vector<unsigned char> _nonce; /*!< Initial Vector generated by encryption method */ std::vector<unsigned char> _nonce; /*!< Initial Vector generated by encryption method */ std::vector<unsigned char> _tag; /*!< Tag vector generated by encryption method */ std::vector<unsigned char> _tag; /*!< Tag vector generated by encryption method */ Loading Loading @@ -107,9 +108,40 @@ public: //! \publicsection */ */ int sign_verif(const std::vector<unsigned char>& p_data, const std::vector<unsigned char>& p_signature); int sign_verif(const std::vector<unsigned char>& p_data, const std::vector<unsigned char>& p_signature); /*! * \fn int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector); * \brief Generate a shared secret key and derive it using KDF2 algorithm. * This method shall be used by the sender. Fresh keys will be genrated for each cyphering operation * \param[in] p_enc_algorithm The encryption algorithm to be used * \param[in] p_peer_public_key_x The recipient public key X-coordinate * \param[in] p_peer_public_key_x The recipient public key Y-coordinate * \remark To get the secret key, uses \see secret_key method * \remark To get the generated symmetric encryption key, uses \see symmetric_encryption_key method * \remark To get the generated nonce vector, uses \see nonce method * \see encrypt methog to encrypt a message based of the generated symetric encryption key * \return 0 on success, -1 otherwise */ int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector); /*! * \fn int generate_and_derive_ephemeral_key(const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y); * \brief Generate a shared secret key and derive it using KDF2 algorithm. * \param[in] p_enc_algorithm The encryption algorithm to be used * \param[in] p_enc_key The private encryption key associated to the public encryption key * \param[in] p_peer_public_key_x The recipient public key X-coordinate * \param[in] p_peer_public_key_x The recipient public key Y-coordinate * \remark To get the secret key, uses \see secret_key method * \remark To get the generated symmetric encryption key, uses \see symmetric_encryption_key method * \remark To get the generated nonce vector, uses \see nonce method * \return 0 on success, -1 otherwise */ int generate_and_derive_ephemeral_key(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_private_enc_key, const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y, std::vector<unsigned char>& p_authentication_vector) { return -1; }; /*! /*! * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \brief Encryption using the specified algorithm. * \brief Encryption using the specified algorithm, the encryption parameters are generated automatically. * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_message The message to be encrypted * \param[in] p_message The message to be encrypted * \param[out] p_enc_message The encrypted message * \param[out] p_enc_message The encrypted message Loading @@ -121,7 +153,7 @@ public: //! \publicsection int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); /*! /*! * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \fn int encrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, const std::vector<unsigned char>& p_nonce, const std::vector<unsigned char>& p_message, std::vector<unsigned char>& p_enc_message); * \brief Encryption using the specified algorithm. * \brief Encryption using the specified algorithm. The encryption parameters are provided by the caller (e.g. ECIES encryption). * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_enc_algorithm The algorithm to use for the encryption * \param[in] p_symmetric_key * \param[in] p_symmetric_key * \param[in] p_nonce * \param[in] p_nonce Loading @@ -146,32 +178,18 @@ public: //! \publicsection * \remark To get the generated tag, uses \see tag method * \remark To get the generated tag, uses \see tag method * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise */ */ int decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_key, 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 decrypt(const encryption_algotithm p_enc_algorithm, const std::vector<unsigned char>& p_symmetric_key, 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); // TODO To be reorganised // TODO To be reorganised /*! * \fn int generate_and_derive_ephemeral_key(const std::vector<unsigned char>& p_public_key_x, const std::vector<unsigned char>& p_public_key_y); * \brief Generate a shared secret key and derive it using KDF2 algorithm. * \param[in] p_peer_public_key_x The recipient public key X-coordinate * \param[in] p_peer_public_key_x The recipient public key Y-coordinate * \remark To get the generated ephemeral key, uses \see ephemeral_key method * \remark To get the generated nonce vector, uses \see nonce method * \remark To get the generated tag, uses \see tag method * \return 0 on success, -1 otherwise */ int generate_and_derive_ephemeral_key(const std::vector<unsigned char>& p_peer_public_enc_key_x, const std::vector<unsigned char>& p_peer_public_enc_key_y); // 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 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); 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>& private_key() const { return _pri_key; }; inline const std::vector<unsigned char>& public_key_x() const { return _pub_key_x; }; inline const std::vector<unsigned char>& public_key_x() const { return _pub_key_x; }; inline const std::vector<unsigned char>& public_key_y() const { return _pub_key_y; }; inline const std::vector<unsigned char>& public_key_y() const { return _pub_key_y; }; inline const std::vector<unsigned char>& ephemeral_key() const { return _eph_key; }; inline const std::vector<unsigned char>& secret_key() const { return _secret_key; }; inline const std::vector<unsigned char>& encryption_key_x() const { return _enc_key_x; }; inline const std::vector<unsigned char>& encryption_key_x() const { return _enc_key_x; }; inline const std::vector<unsigned char>& encryption_key_y() const { return _enc_key_y; }; inline const std::vector<unsigned char>& encryption_key_y() const { return _enc_key_y; }; inline const std::vector<unsigned char>& enc_hmac() const { return _hmac; }; inline const std::vector<unsigned char>& symmetric_encryption_key() const { return _sym_key; }; inline const std::vector<unsigned char>& symmetric_encryption_key() const { return _sym_key; }; inline const std::vector<unsigned char>& nonce() const { return _nonce; }; inline const std::vector<unsigned char>& nonce() const { return _nonce; }; inline const std::vector<unsigned char>& tag() const { return _tag; }; inline const std::vector<unsigned char>& tag() const { return _tag; }; Loading @@ -195,4 +213,11 @@ private: //! \privatesection * \return 0 on success, -1 otherwise * \return 0 on success, -1 otherwise */ */ int public_key_to_bin(std::vector<unsigned char>& p_bin_key); int public_key_to_bin(std::vector<unsigned char>& p_bin_key); /*int multiply_point_with_bn(const EC_POINT &a, const BIGNUM* b, EC_POINT **P); // R: XY-coordinate compressed, S: Share Secret int derive_s_from_private_key(BIGNUM *S, BIGNUM *R); // R: XY-coordinate compressed, S: Share Secret int derive_s_from_public_key(BIGNUM *S, BIGNUM *R);*/ }; // End of class security_ecc }; // End of class security_ecc
ccsrc/Protocols/Security/security_services.cc +4 −0 Original line number Original line Diff line number Diff line Loading @@ -781,3 +781,7 @@ int security_services::read_certificate_from_digest(const OCTETSTRING& p_digest, int security_services::read_private_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_key) const { int security_services::read_private_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_key) const { return _security_db.get()->get_private_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_key); return _security_db.get()->get_private_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_key); } } int security_services::read_private_enc_key(const CHARSTRING& p_certificate_id, OCTETSTRING& p_private_enc_key) const { return _security_db.get()->get_private_enc_key(std::string(static_cast<const char*>(p_certificate_id)), p_private_enc_key); }