Loading...
Searching...
No Matches
lime_crypto_primitives.hpp
Go to the documentation of this file.
/*
lime_crypto_primitives.hpp
@author Johan Pascal
@copyright Copyright (C) 2017 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef lime_crypto_primitives_hpp
#define lime_crypto_primitives_hpp
#include <memory>
#include <vector>
#include "lime_keys.hpp"
#include "lime_defines.hpp"
namespace lime {
/*************************************************************************************************/
/********************** Data Structures **********************************************************/
/*************************************************************************************************/
void cleanBuffer(uint8_t *buffer, size_t size);
template <size_t T>
struct sBuffer : public std::array<uint8_t, T> {
~sBuffer() {cleanBuffer(this->data(), T);};
};
/****************************************************************/
/* Key Exchange Data structures */
/****************************************************************/
template <typename Curve, lime::Xtype dataType>
class X : public sBuffer<static_cast<size_t>(Curve::Xsize(dataType))>{
public :
constexpr static size_t ssize(void) {return Curve::Xsize(dataType);};
X(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::Xsize(dataType), this->begin());}
X() {};
void assign(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::Xsize(dataType), this->begin());}
};
template <typename Curve>
class Xpair {
private:
X<Curve, lime::Xtype::publicKey> m_pubKey;
X<Curve, lime::Xtype::privateKey> m_privKey;
public:
X<Curve, lime::Xtype::privateKey> &privateKey(void) {return m_privKey;};
X<Curve, lime::Xtype::publicKey> &publicKey(void) {return m_pubKey;};
Xpair(X<Curve, lime::Xtype::publicKey> &pub, X<Curve, lime::Xtype::privateKey> &priv):m_pubKey(pub),m_privKey(priv) {};
Xpair() :m_pubKey{},m_privKey{}{};
bool operator==(Xpair<Curve> b) const {return (m_privKey==b.privateKey() && m_pubKey==b.publicKey());};
};
/****************************************************************/
/* Digital Signature Algorithm data structures */
/****************************************************************/
template <typename Curve, lime::DSAtype dataType>
class DSA : public sBuffer<static_cast<size_t>(Curve::DSAsize(dataType))>{
public :
constexpr static size_t ssize(void) {return Curve::DSAsize(dataType);};
DSA(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::DSAsize(dataType), this->begin());}
DSA() {};
void assign(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::DSAsize(dataType), this->begin());}
};
template <typename Curve>
class DSApair {
private:
DSA<Curve, lime::DSAtype::publicKey> m_pubKey;
DSA<Curve, lime::DSAtype::privateKey> m_privKey;
public:
DSA<Curve, lime::DSAtype::privateKey> &privateKey(void) {return m_privKey;};
DSA<Curve, lime::DSAtype::publicKey> &publicKey(void) {return m_pubKey;};
DSApair(DSA<Curve, lime::DSAtype::publicKey> &pub, DSA<Curve, lime::DSAtype::privateKey> &priv):m_pubKey(pub),m_privKey(priv) {};
DSApair() :m_pubKey{},m_privKey{}{};
bool operator==(DSApair<Curve> b) const {return (m_privKey==b.privateKey() && m_pubKey==b.publicKey());};
};
/*************************************************************************************************/
/********************** Crypto Algo interface ****************************************************/
/*************************************************************************************************/
class RNG {
public:
virtual void randomize(sBuffer<lime::settings::DRrandomSeedSize> &buffer) = 0;
virtual uint32_t randomize() = 0;
virtual void randomize(uint8_t *buffer, const size_t size) = 0;
virtual ~RNG() = default;
}; //class RNG
template <typename Curve>
class keyExchange {
public:
/* accessors */
virtual const X<Curve, lime::Xtype::privateKey> get_secret(void) = 0;
virtual const X<Curve, lime::Xtype::publicKey> get_selfPublic(void) = 0;
virtual const X<Curve, lime::Xtype::publicKey> get_peerPublic(void) = 0;
virtual const X<Curve, lime::Xtype::sharedSecret> get_sharedSecret(void) = 0;
/* set keys in context, publics and private keys directly accept Signature formatted keys which are converted to keyExchange format */
virtual void set_secret(const X<Curve, lime::Xtype::privateKey> &secret) = 0;
virtual void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secret) = 0;
virtual void set_selfPublic(const X<Curve, lime::Xtype::publicKey> &selfPublic) = 0;
virtual void set_selfPublic(const DSA<Curve, lime::DSAtype::publicKey> &selfPublic) = 0;
virtual void set_peerPublic(const X<Curve, lime::Xtype::publicKey> &peerPublic) = 0;
virtual void set_peerPublic(const DSA<Curve, lime::DSAtype::publicKey> &peerPublic) = 0;
virtual void createKeyPair(std::shared_ptr<lime::RNG> rng) = 0;
virtual void deriveSelfPublic(void) = 0;
virtual void computeSharedSecret(void) = 0;
virtual ~keyExchange() = default;
}; //class keyExchange
template <typename Curve>
class Signature {
public:
/* accessors */
virtual const DSA<Curve, lime::DSAtype::privateKey> get_secret(void) = 0;
virtual const DSA<Curve, lime::DSAtype::publicKey> get_public(void) = 0;
virtual void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secretKey) = 0;
virtual void set_public(const DSA<Curve, lime::DSAtype::publicKey> &publicKey) = 0;
virtual void createKeyPair(std::shared_ptr<lime::RNG> rng) = 0;
virtual void derivePublic(void) = 0;
virtual void sign(const std::vector<uint8_t> &message, DSA<Curve, lime::DSAtype::signature> &signature) = 0;
virtual void sign(const X<Curve, lime::Xtype::publicKey> &message, DSA<Curve, lime::DSAtype::signature> &signature) = 0;
virtual bool verify(const std::vector<uint8_t> &message, const DSA<Curve, lime::DSAtype::signature> &signature) = 0;
virtual bool verify(const X<Curve, lime::Xtype::publicKey> &message, const DSA<Curve, lime::DSAtype::signature> &signature) = 0;
virtual ~Signature() = default;
}; //class EdDSA
template <typename hashAlgo>
void HMAC(const uint8_t *const key, const size_t keySize, const uint8_t *const input, const size_t inputSize, uint8_t *hash, size_t hashSize);
/* declare template specialisations */
template <> void HMAC<SHA512>(const uint8_t *const key, const size_t keySize, const uint8_t *const input, const size_t inputSize, uint8_t *hash, size_t hashSize);
template <typename hashAlgo, typename infoType>
void HMAC_KDF(const std::vector<uint8_t> &salt, const std::vector<uint8_t> &ikm, const infoType &info, uint8_t *okm, size_t okmSize);
template <typename hashAlgo, typename infoType>
void HMAC_KDF(const uint8_t *const salt, const size_t saltSize, const uint8_t *const ikm, const size_t ikmSize, const infoType &info, uint8_t *output, size_t outputSize);
/************************ AEAD interface *************************************/
template <typename AEADAlgo>
void AEAD_encrypt(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
const uint8_t *const plain, const size_t plainSize, const uint8_t *const AD, const size_t ADSize,
uint8_t *tag, const size_t tagSize, uint8_t *cipher);
template <typename AEADAlgo>
bool AEAD_decrypt(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
const uint8_t *const cipher, const size_t cipherSize, const uint8_t *const AD, const size_t ADSize,
const uint8_t *const tag, const size_t tagSize, uint8_t *plain);
/* declare AEAD template specialisations */
template <> void AEAD_encrypt<AES256GCM>(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
const uint8_t *const plain, const size_t plainSize, const uint8_t *const AD, const size_t ADSize,
uint8_t *tag, const size_t tagSize, uint8_t *cipher);
template <> bool AEAD_decrypt<AES256GCM>(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
const uint8_t *const cipher, const size_t cipherSize, const uint8_t *const AD, const size_t ADSize,
const uint8_t *const tag, const size_t tagSize, uint8_t *plain);
/*************************************************************************************************/
/********************** Factory Functions ********************************************************/
/*************************************************************************************************/
/* Use these to instantiate an object as they will pick the correct undurlying implemenation of virtual classes */
std::shared_ptr<RNG> make_RNG();
template <typename Curve>
std::shared_ptr<keyExchange<Curve>> make_keyExchange();
template <typename Curve>
std::shared_ptr<Signature<Curve>> make_Signature();
/*************************************************************************************************/
/********************** Template Instanciation ***************************************************/
/*************************************************************************************************/
/* this templates are instanciated once in the lime_crypto_primitives.cpp file, explicitly tell anyone including this header that there is no need to re-instanciate them */
extern template void HMAC_KDF<SHA512, std::vector<uint8_t>>(const std::vector<uint8_t> &salt, const std::vector<uint8_t> &ikm, const std::vector<uint8_t> &info, uint8_t *output, size_t outputSize);
extern template void HMAC_KDF<SHA512, std::string>(const std::vector<uint8_t> &salt, const std::vector<uint8_t> &ikm, const std::string &info, uint8_t *output, size_t outputSize);
extern template void HMAC_KDF<SHA512, std::vector<uint8_t>>(const uint8_t *const salt, const size_t saltSize, const uint8_t *const ikm, const size_t ikmSize, const std::vector<uint8_t> &info, uint8_t *output, size_t outputSize);
extern template void HMAC_KDF<SHA512, std::string>(const uint8_t *const salt, const size_t saltSize, const uint8_t *const ikm, const size_t ikmSize, const std::string &info, uint8_t *output, size_t outputSize);
#ifdef EC25519_ENABLED
extern template std::shared_ptr<keyExchange<C255>> make_keyExchange();
extern template std::shared_ptr<Signature<C255>> make_Signature();
extern template class X<C255, lime::Xtype::publicKey>;
extern template class X<C255, lime::Xtype::privateKey>;
extern template class X<C255, lime::Xtype::sharedSecret>;
extern template class Xpair<C255>;
extern template class DSA<C255, lime::DSAtype::publicKey>;
extern template class DSA<C255, lime::DSAtype::privateKey>;
extern template class DSA<C255, lime::DSAtype::signature>;
extern template class DSApair<C255>;
#endif // EC25519_ENABLED
#ifdef EC448_ENABLED
extern template std::shared_ptr<keyExchange<C448>> make_keyExchange();
extern template std::shared_ptr<Signature<C448>> make_Signature();
extern template class X<C448, lime::Xtype::publicKey>;
extern template class X<C448, lime::Xtype::privateKey>;
extern template class X<C448, lime::Xtype::sharedSecret>;
extern template class Xpair<C448>;
extern template class DSA<C448, lime::DSAtype::publicKey>;
extern template class DSA<C448, lime::DSAtype::privateKey>;
extern template class DSA<C448, lime::DSAtype::signature>;
extern template class DSApair<C448>;
#endif // EC448_ENABLED
} // namespace lime
#endif //lime_crypto_primitives_hpp
lime::DSA
Base buffer definition for DSA data structure.
Definition lime_crypto_primitives.hpp:97
lime::DSA::ssize
static constexpr size_t ssize(void)
provide a static size function to be able to call the function not on an object
Definition lime_crypto_primitives.hpp:100
lime::DSA::DSA
DSA()
Definition lime_crypto_primitives.hpp:103
lime::DSA::assign
void assign(std::vector< uint8_t >::const_iterator buffer)
copy from a std::vector<uint8_t>
Definition lime_crypto_primitives.hpp:105
lime::DSA::DSA
DSA(std::vector< uint8_t >::const_iterator buffer)
contruct from a std::vector<uint8_t>
Definition lime_crypto_primitives.hpp:102
lime::DSApair
Key pair structure for DSA algorithm.
Definition lime_crypto_primitives.hpp:112
lime::DSApair::privateKey
DSA< Curve, lime::DSAtype::privateKey > & privateKey(void)
access the private key
Definition lime_crypto_primitives.hpp:118
lime::DSApair::operator==
bool operator==(DSApair< Curve > b) const
== operator assert that public and private keys are the same
Definition lime_crypto_primitives.hpp:125
lime::DSApair::publicKey
DSA< Curve, lime::DSAtype::publicKey > & publicKey(void)
access the public key
Definition lime_crypto_primitives.hpp:120
lime::DSApair::DSApair
DSApair(DSA< Curve, lime::DSAtype::publicKey > &pub, DSA< Curve, lime::DSAtype::privateKey > &priv)
copy construct a key pair from public and private keys (no verification on validity of keys is perfor...
Definition lime_crypto_primitives.hpp:122
lime::DSApair::DSApair
DSApair()
Definition lime_crypto_primitives.hpp:123
lime::RNG
Random number generator interface.
Definition lime_crypto_primitives.hpp:142
lime::RNG::randomize
virtual void randomize(uint8_t *buffer, const size_t size)=0
lime::RNG::randomize
virtual void randomize(sBuffer< lime::settings::DRrandomSeedSize > &buffer)=0
fill the given RandomSeed buffer with Random bytes
lime::RNG::randomize
virtual uint32_t randomize()=0
Generate a 32 bits unsigned integer(used to generate keys Id) The MSbit is forced to 0 to avoid deali...
lime::RNG::~RNG
virtual ~RNG()=default
lime::Signature
Digital Signature interface.
Definition lime_crypto_primitives.hpp:237
lime::Signature::derivePublic
virtual void derivePublic(void)=0
Compute the public key using the secret already set in context.
lime::Signature::get_secret
virtual const DSA< Curve, lime::DSAtype::privateKey > get_secret(void)=0
Secret key.
lime::Signature::sign
virtual void sign(const std::vector< uint8_t > &message, DSA< Curve, lime::DSAtype::signature > &signature)=0
Sign a message using the key pair previously set in the object.
lime::Signature::set_secret
virtual void set_secret(const DSA< Curve, lime::DSAtype::privateKey > &secretKey)=0
Secret key.
lime::Signature::sign
virtual void sign(const X< Curve, lime::Xtype::publicKey > &message, DSA< Curve, lime::DSAtype::signature > &signature)=0
lime::Signature::createKeyPair
virtual void createKeyPair(std::shared_ptr< lime::RNG > rng)=0
generate a new random EdDSA key pair
lime::Signature::~Signature
virtual ~Signature()=default
lime::Signature::get_public
virtual const DSA< Curve, lime::DSAtype::publicKey > get_public(void)=0
Public key.
lime::Signature::verify
virtual bool verify(const std::vector< uint8_t > &message, const DSA< Curve, lime::DSAtype::signature > &signature)=0
Verify a message signature using the public key previously set in the object.
lime::Signature::verify
virtual bool verify(const X< Curve, lime::Xtype::publicKey > &message, const DSA< Curve, lime::DSAtype::signature > &signature)=0
lime::Signature::set_public
virtual void set_public(const DSA< Curve, lime::DSAtype::publicKey > &publicKey)=0
Public key.
lime::X
Base buffer definition for Key Exchange data structure.
Definition lime_crypto_primitives.hpp:56
lime::X::X
X()
Definition lime_crypto_primitives.hpp:62
lime::X::X
X(std::vector< uint8_t >::const_iterator buffer)
construct from a std::vector<uint8_t>
Definition lime_crypto_primitives.hpp:61
lime::X::assign
void assign(std::vector< uint8_t >::const_iterator buffer)
copy from a std::vector<uint8_t>
Definition lime_crypto_primitives.hpp:64
lime::X::ssize
static constexpr size_t ssize(void)
provide a static size function to be able to call the function not on an object
Definition lime_crypto_primitives.hpp:59
lime::Xpair
Key pair structure for key exchange algorithm.
Definition lime_crypto_primitives.hpp:71
lime::Xpair::publicKey
X< Curve, lime::Xtype::publicKey > & publicKey(void)
access the public key
Definition lime_crypto_primitives.hpp:79
lime::Xpair::operator==
bool operator==(Xpair< Curve > b) const
== operator assert that public and private keys are the same
Definition lime_crypto_primitives.hpp:84
lime::Xpair::Xpair
Xpair()
Definition lime_crypto_primitives.hpp:82
lime::Xpair::privateKey
X< Curve, lime::Xtype::privateKey > & privateKey(void)
access the private key
Definition lime_crypto_primitives.hpp:77
lime::Xpair::Xpair
Xpair(X< Curve, lime::Xtype::publicKey > &pub, X< Curve, lime::Xtype::privateKey > &priv)
copy construct a key pair from public and private keys (no verification on validity of keys is perfor...
Definition lime_crypto_primitives.hpp:81
lime::keyExchange
Key exchange interface.
Definition lime_crypto_primitives.hpp:177
lime::keyExchange::set_secret
virtual void set_secret(const X< Curve, lime::Xtype::privateKey > &secret)=0
set Secret key
lime::keyExchange::get_selfPublic
virtual const X< Curve, lime::Xtype::publicKey > get_selfPublic(void)=0
get Self Public key
lime::keyExchange::~keyExchange
virtual ~keyExchange()=default
lime::keyExchange::set_secret
virtual void set_secret(const DSA< Curve, lime::DSAtype::privateKey > &secret)=0
lime::keyExchange::get_peerPublic
virtual const X< Curve, lime::Xtype::publicKey > get_peerPublic(void)=0
get Peer Public key
lime::keyExchange::get_sharedSecret
virtual const X< Curve, lime::Xtype::sharedSecret > get_sharedSecret(void)=0
get shared secret when exchange is completed
lime::keyExchange::createKeyPair
virtual void createKeyPair(std::shared_ptr< lime::RNG > rng)=0
generate a new random key pair
lime::keyExchange::set_selfPublic
virtual void set_selfPublic(const DSA< Curve, lime::DSAtype::publicKey > &selfPublic)=0
lime::keyExchange::set_selfPublic
virtual void set_selfPublic(const X< Curve, lime::Xtype::publicKey > &selfPublic)=0
set Self Public key
lime::keyExchange::set_peerPublic
virtual void set_peerPublic(const DSA< Curve, lime::DSAtype::publicKey > &peerPublic)=0
lime::keyExchange::set_peerPublic
virtual void set_peerPublic(const X< Curve, lime::Xtype::publicKey > &peerPublic)=0
set Peer Public key
lime::keyExchange::get_secret
virtual const X< Curve, lime::Xtype::privateKey > get_secret(void)=0
get Secret key
lime::keyExchange::computeSharedSecret
virtual void computeSharedSecret(void)=0
Perform the shared secret computation, it is then available in the object via get_sharedSecret.
lime::keyExchange::deriveSelfPublic
virtual void deriveSelfPublic(void)=0
Compute the self public key using the secret already set in context.
lime_defines.hpp
lime_keys.hpp
lime
Definition lime.cpp:30
lime::make_RNG
std::shared_ptr< RNG > make_RNG()
Definition lime_crypto_primitives.cpp:76
lime::AEAD_decrypt< AES256GCM >
bool AEAD_decrypt< AES256GCM >(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize, const uint8_t *const cipher, const size_t cipherSize, const uint8_t *const AD, const size_t ADSize, const uint8_t *const tag, const size_t tagSize, uint8_t *plain)
Definition lime_crypto_primitives.cpp:437
lime::HMAC_KDF< SHA512, std::string >
template void HMAC_KDF< SHA512, std::string >(const uint8_t *const salt, const size_t saltSize, const uint8_t *const ikm, const size_t ikmSize, const std::string &info, uint8_t *output, size_t outputSize)
lime::make_Signature
std::shared_ptr< Signature< Curve > > make_Signature()
Definition lime_crypto_primitives.cpp:353
lime::DSAtype::signature
@ signature
Definition lime_keys.hpp:39
lime::make_keyExchange
std::shared_ptr< keyExchange< Curve > > make_keyExchange()
Definition lime_crypto_primitives.cpp:348
lime::Xtype::publicKey
@ publicKey
Definition lime_keys.hpp:34
lime::AEAD_encrypt< AES256GCM >
void AEAD_encrypt< AES256GCM >(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize, const uint8_t *const plain, const size_t plainSize, const uint8_t *const AD, const size_t ADSize, uint8_t *tag, const size_t tagSize, uint8_t *cipher)
Definition lime_crypto_primitives.cpp:424
lime::AEAD_decrypt
bool AEAD_decrypt(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize, const uint8_t *const cipher, const size_t cipherSize, const uint8_t *const AD, const size_t ADSize, const uint8_t *const tag, const size_t tagSize, uint8_t *plain)
Authenticate and Decrypt using scheme given as template parameter.
Definition lime_crypto_primitives.cpp:415
lime::AEAD_encrypt
void AEAD_encrypt(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize, const uint8_t *const plain, const size_t plainSize, const uint8_t *const AD, const size_t ADSize, uint8_t *tag, const size_t tagSize, uint8_t *cipher)
Encrypt and tag using scheme given as template parameter.
Definition lime_crypto_primitives.cpp:407
lime::HMAC_KDF
void HMAC_KDF(const uint8_t *const salt, const size_t saltSize, const uint8_t *const ikm, const size_t ikmSize, const infoType &info, uint8_t *output, size_t outputSize)
Definition lime_crypto_primitives.cpp:372
lime::HMAC
void HMAC(const uint8_t *const key, const size_t keySize, const uint8_t *const input, const size_t inputSize, uint8_t *hash, size_t hashSize)
templated HMAC
Definition lime_crypto_primitives.cpp:360
lime::cleanBuffer
void cleanBuffer(uint8_t *buffer, size_t size)
force a buffer values to zero in a way that shall prevent the compiler from optimizing it out
Definition lime_crypto_primitives.cpp:479
lime::HMAC< SHA512 >
void HMAC< SHA512 >(const uint8_t *const key, const size_t keySize, const uint8_t *const input, const size_t inputSize, uint8_t *hash, size_t hashSize)
Definition lime_crypto_primitives.cpp:366
lime::sBuffer
auto clean fixed size buffer(std::array based)
Definition lime_crypto_primitives.hpp:42
lime::sBuffer::~sBuffer
~sBuffer()
zeroise all buffer when done
Definition lime_crypto_primitives.hpp:44