lime
Lime is a C++ library implementing Open Whisper System Signal protocol
lime_crypto_primitives.hpp
Go to the documentation of this file.
1/*
2 lime_crypto_primitives.hpp
3 @author Johan Pascal
4 @copyright Copyright (C) 2017 Belledonne Communications SARL
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef lime_crypto_primitives_hpp
21#define lime_crypto_primitives_hpp
22
23#include <memory>
24#include <vector>
25
26#include "lime_keys.hpp"
27#include "lime_defines.hpp"
28
29namespace lime {
30/*************************************************************************************************/
31/********************** Data Structures **********************************************************/
32/*************************************************************************************************/
33
34 void cleanBuffer(uint8_t *buffer, size_t size);
35
41 template <size_t T>
42 struct sBuffer : public std::array<uint8_t, T> {
44 ~sBuffer() {cleanBuffer(this->data(), T);};
45 };
46
47 /****************************************************************/
48 /* Key Exchange Data structures */
49 /****************************************************************/
55 template <typename Curve, lime::Xtype dataType>
56 class X : public sBuffer<static_cast<size_t>(Curve::Xsize(dataType))>{
57 public :
59 constexpr static size_t ssize(void) {return Curve::Xsize(dataType);};
61 X(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::Xsize(dataType), this->begin());}
62 X() {};
64 void assign(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::Xsize(dataType), this->begin());}
65 };
66
70 template <typename Curve>
71 class Xpair {
72 private:
75 public:
81 Xpair(X<Curve, lime::Xtype::publicKey> &pub, X<Curve, lime::Xtype::privateKey> &priv):m_pubKey(pub),m_privKey(priv) {};
82 Xpair() :m_pubKey{},m_privKey{}{};
84 bool operator==(Xpair<Curve> b) const {return (m_privKey==b.privateKey() && m_pubKey==b.publicKey());};
85
86 };
87
88 /****************************************************************/
89 /* Digital Signature Algorithm data structures */
90 /****************************************************************/
96 template <typename Curve, lime::DSAtype dataType>
97 class DSA : public sBuffer<static_cast<size_t>(Curve::DSAsize(dataType))>{
98 public :
100 constexpr static size_t ssize(void) {return Curve::DSAsize(dataType);};
102 DSA(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::DSAsize(dataType), this->begin());}
103 DSA() {};
105 void assign(std::vector<uint8_t>::const_iterator buffer) {std::copy_n(buffer, Curve::DSAsize(dataType), this->begin());}
106 };
107
111 template <typename Curve>
112 class DSApair {
113 private:
116 public:
123 DSApair() :m_pubKey{},m_privKey{}{};
125 bool operator==(DSApair<Curve> b) const {return (m_privKey==b.privateKey() && m_pubKey==b.publicKey());};
126 };
127
128
129/*************************************************************************************************/
130/********************** Crypto Algo interface ****************************************************/
131/*************************************************************************************************/
132
142class RNG {
143 public:
150
158 virtual uint32_t randomize() = 0;
159
165 virtual void randomize(uint8_t *buffer, const size_t size) = 0;
166
167 virtual ~RNG() = default;
168}; //class RNG
169
176template <typename Curve>
178 public:
179 /* accessors */
188
189 /* set keys in context, publics and private keys directly accept Signature formatted keys which are converted to keyExchange format */
191 virtual void set_secret(const X<Curve, lime::Xtype::privateKey> &secret) = 0;
196 virtual void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secret) = 0;
198 virtual void set_selfPublic(const X<Curve, lime::Xtype::publicKey> &selfPublic) = 0;
203 virtual void set_selfPublic(const DSA<Curve, lime::DSAtype::publicKey> &selfPublic) = 0;
205 virtual void set_peerPublic(const X<Curve, lime::Xtype::publicKey> &peerPublic) = 0;
210 virtual void set_peerPublic(const DSA<Curve, lime::DSAtype::publicKey> &peerPublic) = 0;
211
217 virtual void createKeyPair(std::shared_ptr<lime::RNG> rng) = 0;
218
222 virtual void deriveSelfPublic(void) = 0;
223
227 virtual void computeSharedSecret(void) = 0;
228 virtual ~keyExchange() = default;
229}; //class keyExchange
230
236template <typename Curve>
238 public:
239 /* accessors */
244
246 virtual void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secretKey) = 0;
248 virtual void set_public(const DSA<Curve, lime::DSAtype::publicKey> &publicKey) = 0;
249
255 virtual void createKeyPair(std::shared_ptr<lime::RNG> rng) = 0;
256
260 virtual void derivePublic(void) = 0;
261
268 virtual void sign(const std::vector<uint8_t> &message, DSA<Curve, lime::DSAtype::signature> &signature) = 0;
274
283 virtual bool verify(const std::vector<uint8_t> &message, const DSA<Curve, lime::DSAtype::signature> &signature) = 0;
288 virtual bool verify(const X<Curve, lime::Xtype::publicKey> &message, const DSA<Curve, lime::DSAtype::signature> &signature) = 0;
289
290 virtual ~Signature() = default;
291}; //class EdDSA
292
306template <typename hashAlgo>
307void 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);
308/* declare template specialisations */
309template <> 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);
310
339template <typename hashAlgo, typename infoType>
340void HMAC_KDF(const std::vector<uint8_t> &salt, const std::vector<uint8_t> &ikm, const infoType &info, uint8_t *okm, size_t okmSize);
345template <typename hashAlgo, typename infoType>
346void 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);
347
348
349/************************ AEAD interface *************************************/
350
366template <typename AEADAlgo>
367void AEAD_encrypt(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
368 const uint8_t *const plain, const size_t plainSize, const uint8_t *const AD, const size_t ADSize,
369 uint8_t *tag, const size_t tagSize, uint8_t *cipher);
370
388template <typename AEADAlgo>
389bool AEAD_decrypt(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
390 const uint8_t *const cipher, const size_t cipherSize, const uint8_t *const AD, const size_t ADSize,
391 const uint8_t *const tag, const size_t tagSize, uint8_t *plain);
392
393/* declare AEAD template specialisations */
394template <> void AEAD_encrypt<AES256GCM>(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
395 const uint8_t *const plain, const size_t plainSize, const uint8_t *const AD, const size_t ADSize,
396 uint8_t *tag, const size_t tagSize, uint8_t *cipher);
397
398template <> bool AEAD_decrypt<AES256GCM>(const uint8_t *const key, const size_t keySize, const uint8_t *const IV, const size_t IVSize,
399 const uint8_t *const cipher, const size_t cipherSize, const uint8_t *const AD, const size_t ADSize,
400 const uint8_t *const tag, const size_t tagSize, uint8_t *plain);
401
402
403/*************************************************************************************************/
404/********************** Factory Functions ********************************************************/
405/*************************************************************************************************/
406/* Use these to instantiate an object as they will pick the correct undurlying implemenation of virtual classes */
407std::shared_ptr<RNG> make_RNG();
408
409template <typename Curve>
410std::shared_ptr<keyExchange<Curve>> make_keyExchange();
411
412template <typename Curve>
413std::shared_ptr<Signature<Curve>> make_Signature();
414
415/*************************************************************************************************/
416/********************** Template Instanciation ***************************************************/
417/*************************************************************************************************/
418/* 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 */
419extern 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);
420extern 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);
421extern 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);
422extern 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);
423
424#ifdef EC25519_ENABLED
425 extern template std::shared_ptr<keyExchange<C255>> make_keyExchange();
426 extern template std::shared_ptr<Signature<C255>> make_Signature();
427 extern template class X<C255, lime::Xtype::publicKey>;
428 extern template class X<C255, lime::Xtype::privateKey>;
429 extern template class X<C255, lime::Xtype::sharedSecret>;
430 extern template class Xpair<C255>;
431 extern template class DSA<C255, lime::DSAtype::publicKey>;
432 extern template class DSA<C255, lime::DSAtype::privateKey>;
433 extern template class DSA<C255, lime::DSAtype::signature>;
434 extern template class DSApair<C255>;
435#endif // EC25519_ENABLED
436
437#ifdef EC448_ENABLED
438 extern template std::shared_ptr<keyExchange<C448>> make_keyExchange();
439 extern template std::shared_ptr<Signature<C448>> make_Signature();
440 extern template class X<C448, lime::Xtype::publicKey>;
441 extern template class X<C448, lime::Xtype::privateKey>;
442 extern template class X<C448, lime::Xtype::sharedSecret>;
443 extern template class Xpair<C448>;
444 extern template class DSA<C448, lime::DSAtype::publicKey>;
445 extern template class DSA<C448, lime::DSAtype::privateKey>;
446 extern template class DSA<C448, lime::DSAtype::signature>;
447 extern template class DSApair<C448>;
448#endif // EC448_ENABLED
449
450} // namespace lime
451
452#endif //lime_crypto_primitives_hpp
453
454
Base buffer definition for DSA data structure.
Definition: lime_crypto_primitives.hpp:97
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
DSA()
Definition: lime_crypto_primitives.hpp:103
void assign(std::vector< uint8_t >::const_iterator buffer)
copy from a std::vector<uint8_t>
Definition: lime_crypto_primitives.hpp:105
DSA(std::vector< uint8_t >::const_iterator buffer)
contruct from a std::vector<uint8_t>
Definition: lime_crypto_primitives.hpp:102
Key pair structure for DSA algorithm.
Definition: lime_crypto_primitives.hpp:112
DSA< Curve, lime::DSAtype::privateKey > & privateKey(void)
access the private key
Definition: lime_crypto_primitives.hpp:118
bool operator==(DSApair< Curve > b) const
== operator assert that public and private keys are the same
Definition: lime_crypto_primitives.hpp:125
DSA< Curve, lime::DSAtype::publicKey > & publicKey(void)
access the public key
Definition: lime_crypto_primitives.hpp:120
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
DSApair()
Definition: lime_crypto_primitives.hpp:123
Random number generator interface.
Definition: lime_crypto_primitives.hpp:142
virtual void randomize(uint8_t *buffer, const size_t size)=0
virtual void randomize(sBuffer< lime::settings::DRrandomSeedSize > &buffer)=0
fill the given RandomSeed buffer with Random bytes
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...
virtual ~RNG()=default
Digital Signature interface.
Definition: lime_crypto_primitives.hpp:237
virtual void derivePublic(void)=0
Compute the public key using the secret already set in context.
virtual bool verify(const X< Curve, lime::Xtype::publicKey > &message, const DSA< Curve, lime::DSAtype::signature > &signature)=0
virtual const DSA< Curve, lime::DSAtype::privateKey > get_secret(void)=0
Secret key.
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.
virtual void set_secret(const DSA< Curve, lime::DSAtype::privateKey > &secretKey)=0
Secret key.
virtual void createKeyPair(std::shared_ptr< lime::RNG > rng)=0
generate a new random EdDSA key pair
virtual void sign(const X< Curve, lime::Xtype::publicKey > &message, DSA< Curve, lime::DSAtype::signature > &signature)=0
virtual ~Signature()=default
virtual const DSA< Curve, lime::DSAtype::publicKey > get_public(void)=0
Public key.
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.
virtual void set_public(const DSA< Curve, lime::DSAtype::publicKey > &publicKey)=0
Public key.
Base buffer definition for Key Exchange data structure.
Definition: lime_crypto_primitives.hpp:56
X()
Definition: lime_crypto_primitives.hpp:62
X(std::vector< uint8_t >::const_iterator buffer)
construct from a std::vector<uint8_t>
Definition: lime_crypto_primitives.hpp:61
void assign(std::vector< uint8_t >::const_iterator buffer)
copy from a std::vector<uint8_t>
Definition: lime_crypto_primitives.hpp:64
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
Key pair structure for key exchange algorithm.
Definition: lime_crypto_primitives.hpp:71
X< Curve, lime::Xtype::publicKey > & publicKey(void)
access the public key
Definition: lime_crypto_primitives.hpp:79
bool operator==(Xpair< Curve > b) const
== operator assert that public and private keys are the same
Definition: lime_crypto_primitives.hpp:84
Xpair()
Definition: lime_crypto_primitives.hpp:82
X< Curve, lime::Xtype::privateKey > & privateKey(void)
access the private key
Definition: lime_crypto_primitives.hpp:77
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
Key exchange interface.
Definition: lime_crypto_primitives.hpp:177
virtual void set_secret(const X< Curve, lime::Xtype::privateKey > &secret)=0
set Secret key
virtual const X< Curve, lime::Xtype::publicKey > get_selfPublic(void)=0
get Self Public key
virtual ~keyExchange()=default
virtual void set_secret(const DSA< Curve, lime::DSAtype::privateKey > &secret)=0
virtual const X< Curve, lime::Xtype::publicKey > get_peerPublic(void)=0
get Peer Public key
virtual const X< Curve, lime::Xtype::sharedSecret > get_sharedSecret(void)=0
get shared secret when exchange is completed
virtual void createKeyPair(std::shared_ptr< lime::RNG > rng)=0
generate a new random key pair
virtual void set_selfPublic(const DSA< Curve, lime::DSAtype::publicKey > &selfPublic)=0
virtual void set_selfPublic(const X< Curve, lime::Xtype::publicKey > &selfPublic)=0
set Self Public key
virtual void set_peerPublic(const DSA< Curve, lime::DSAtype::publicKey > &peerPublic)=0
virtual void set_peerPublic(const X< Curve, lime::Xtype::publicKey > &peerPublic)=0
set Peer Public key
virtual const X< Curve, lime::Xtype::privateKey > get_secret(void)=0
get Secret key
virtual void computeSharedSecret(void)=0
Perform the shared secret computation, it is then available in the object via get_sharedSecret.
virtual void deriveSelfPublic(void)=0
Compute the self public key using the secret already set in context.
Definition: lime.cpp:30
std::shared_ptr< RNG > make_RNG()
Definition: lime_crypto_primitives.cpp:76
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
std::shared_ptr< Signature< Curve > > make_Signature()
Definition: lime_crypto_primitives.cpp:353
std::shared_ptr< keyExchange< Curve > > make_keyExchange()
Definition: lime_crypto_primitives.cpp:348
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
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
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
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
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
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
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
auto clean fixed size buffer(std::array based)
Definition: lime_crypto_primitives.hpp:42
~sBuffer()
zeroise all buffer when done
Definition: lime_crypto_primitives.hpp:44