lime
Lime is a C++ library implementing Open Whisper System Signal protocol
Namespaces | Classes | Typedefs | Enumerations | Functions | Variables
lime Namespace Reference

Namespaces

 double_ratchet_protocol
 Group in this namespace all the functions related to building or parsing double ratchet packets.
 
 settings
 Hold constants definition used as settings in all components of the lime library.
 
 x3dh_protocol
 Group in this namespace all the functions related to building or parsing x3dh packets.
 

Classes

struct  AES256GCM
 AES256GCM buffers size definition. More...
 
class  bctbx_ECDH
 a wrapper around bctoolbox key exchange algorithms, implements the keyExchange interface More...
 
class  bctbx_EDDSA
 a wrapper around bctoolbox signature algorithms, implements the Signature interface More...
 
class  bctbx_RNG
 A wrapper around the bctoolbox Random Number Generator, implements the RNG interface. More...
 
struct  C255
 curve 25519 data types size definition More...
 
struct  C448
 curve 448-goldilocks data types size definition More...
 
struct  callbackUserData
 structure holding user data while waiting for callback from X3DH server response processing More...
 
class  Db
 Database access class. More...
 
class  DR
 store a Double Rachet session. More...
 
class  DSA
 Base buffer definition for DSA data structure. More...
 
class  DSApair
 Key pair structure for DSA algorithm. More...
 
class  keyExchange
 Key exchange interface. More...
 
class  Lime
 Implement the abstract class LimeGeneric. More...
 
class  LimeGeneric
 A pure abstract class defining the API to encrypt/decrypt/manage user and its keys. More...
 
class  LimeManager
 Manage several Lime objects(one is needed for each local user). More...
 
struct  ReceiverKeyChain
 Chain storing the DH and MKs associated with Nr(uint16_t map index) More...
 
struct  RecipientData
 The encrypt function input/output data structure. More...
 
struct  RecipientInfos
 extend the RecipientData to add a Double Ratchet session shared with the recipient More...
 
class  RNG
 Random number generator interface. More...
 
struct  sBuffer
 auto clean fixed size buffer(std::array based) More...
 
struct  SHA512
 SHA512 buffer size definition. More...
 
class  Signature
 Digital Signature interface. More...
 
class  X
 Base buffer definition for Key Exchange data structure. More...
 
struct  X3DH_peerBundle
 Holds everything found in a key bundle received from X3DH server. More...
 
class  Xpair
 Key pair structure for key exchange algorithm. More...
 

Typedefs

using DRChainKey = lime::sBuffer< lime::settings::DRChainKeySize >
 
using DRMKey = lime::sBuffer< lime::settings::DRMessageKeySize+lime::settings::DRMessageIVSize >
 
using SharedADBuffer = std::array< uint8_t, lime::settings::DRSessionSharedADSize >
 
using limeCallback = std::function< void(const lime::CallbackReturn status, const std::string message)>
 Callback use to give a status on asynchronous operation. More...
 
using limeX3DHServerResponseProcess = std::function< void(int responseCode, const std::vector< uint8_t > &responseBody)>
 Get the response from server. The external service providing secure communication to the X3DH server shall forward to lime library the server's response. More...
 
using limeX3DHServerPostData = std::function< void(const std::string &url, const std::string &from, const std::vector< uint8_t > &message, const limeX3DHServerResponseProcess &reponseProcess)>
 Post a message to the X3DH server. More...
 

Enumerations

enum  DRSessionDbStatus : uint8_t {
  DRSessionDbStatus::clean, DRSessionDbStatus::dirty_encrypt, DRSessionDbStatus::dirty_decrypt, DRSessionDbStatus::dirty_ratchet,
  DRSessionDbStatus::dirty
}
 the possible status of session regarding the Local Storage More...
 
enum  network_state : uint8_t { network_state::done =0x00, network_state::sendSPk =0x01, network_state::sendOPk =0x02 }
 
enum  Xtype { Xtype::publicKey, Xtype::privateKey, Xtype::sharedSecret }
 List of data types used by key Echange algorithm. More...
 
enum  DSAtype { DSAtype::publicKey, DSAtype::privateKey, DSAtype::signature }
 List of data types used by Signature algorithm. More...
 
enum  X3DHKeyBundleFlag : uint8_t { X3DHKeyBundleFlag::noOPk =0, X3DHKeyBundleFlag::OPk =1, X3DHKeyBundleFlag::noBundle =2 }
 Set possible values for a flag in the keyBundle X3DH packet. More...
 
enum  CurveId : uint8_t { CurveId::unset =0, CurveId::c25519 =1, CurveId::c448 =2 }
 
enum  EncryptionPolicy { EncryptionPolicy::DRMessage, EncryptionPolicy::cipherMessage, EncryptionPolicy::optimizeUploadSize, EncryptionPolicy::optimizeGlobalBandwidth }
 
enum  PeerDeviceStatus : uint8_t {
  PeerDeviceStatus::untrusted =0, PeerDeviceStatus::trusted =1, PeerDeviceStatus::unsafe =2, PeerDeviceStatus::fail,
  PeerDeviceStatus::unknown
}
 
enum  CallbackReturn : uint8_t { CallbackReturn::success, CallbackReturn::fail }
 

Functions

std::shared_ptr< LimeGenericinsert_LimeUser (const std::string &dbFilename, const std::string &deviceId, const std::string &url, const lime::CurveId curve, const uint16_t OPkInitialBatchSize, const limeX3DHServerPostData &X3DH_post_data, const limeCallback &callback, std::shared_ptr< std::recursive_mutex > db_mutex)
 : Insert user in database and return a pointer to the control class instanciating the appropriate Lime children class More...
 
std::shared_ptr< LimeGenericload_LimeUser (const std::string &dbFilename, const std::string &deviceId, const limeX3DHServerPostData &X3DH_post_data, std::shared_ptr< std::recursive_mutex > db_mutex, const bool allStatus)
 : Load user from database and return a pointer to the control class instanciating the appropriate Lime children class More...
 
std::shared_ptr< RNGmake_RNG ()
 
template<typename Curve >
bctbx_EDDSAContext_t * bctbx_EDDSAInit (void)
 
template<typename Curve >
bctbx_ECDHContext_t * bctbx_ECDHInit (void)
 
template<typename Curve >
std::shared_ptr< keyExchange< Curve > > make_keyExchange ()
 
template<typename Curve >
std::shared_ptr< Signature< Curve > > make_Signature ()
 
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)
 templated HMAC More...
 
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 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)
 
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)
 HKDF as described in RFC5869. More...
 
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)
 
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)
 
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)
 
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)
 
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)
 Encrypt and tag using scheme given as template parameter. More...
 
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)
 Authenticate and Decrypt using scheme given as template parameter. More...
 
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)
 
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 More...
 
template<typename Curve >
static void KDF_RK (DRChainKey &RK, DRChainKey &CK, const X< Curve, lime::Xtype::sharedSecret > &dh_out) noexcept
 Key Derivation Function used in Root key/Diffie-Hellman Ratchet chain. More...
 
static void KDF_CK (DRChainKey &CK, DRMKey &MK) noexcept
 Key Derivation Function used in Symmetric key ratchet chain. More...
 
static bool decrypt (const lime::DRMKey &MK, const std::vector< uint8_t > &ciphertext, const size_t headerSize, std::vector< uint8_t > &AD, std::vector< uint8_t > &plaintext)
 Decrypt as described is spec section 3.1. More...
 
static bool decrypt (const lime::DRMKey &MK, const std::vector< uint8_t > &ciphertext, const size_t headerSize, std::vector< uint8_t > &AD, sBuffer< lime::settings::DRrandomSeedSize > &plaintext)
 
template<typename Curve >
void encryptMessage (std::vector< RecipientInfos< Curve >> &recipients, const std::vector< uint8_t > &plaintext, const std::string &recipientUserId, const std::string &sourceDeviceId, std::vector< uint8_t > &cipherMessage, const lime::EncryptionPolicy encryptionPolicy)
 Encrypt a message to all recipients, identified by their device id. More...
 
template<typename Curve >
std::shared_ptr< DR< Curve > > decryptMessage (const std::string &sourceDeviceId, const std::string &recipientDeviceId, const std::string &recipientUserId, std::vector< std::shared_ptr< DR< Curve >>> &DRSessions, const std::vector< uint8_t > &DRmessage, const std::vector< uint8_t > &cipherMessage, std::vector< uint8_t > &plaintext)
 Decrypt a message. More...
 

Variables

const std::array< std::uint8_t, 1 > hkdf_ck_info {{0x02}}
 
const std::array< std::uint8_t, 1 > hkdf_mk_info {{0x01}}
 

Typedef Documentation

◆ DRChainKey

Double Rachet chain keys: Root key, Sender and receiver keys are 32 bytes arrays

◆ DRMKey

Double Ratchet Message keys : 32 bytes of encryption key followed by 16 bytes of IV

◆ limeCallback

using lime::limeCallback = typedef std::function<void(const lime::CallbackReturn status, const std::string message)>

Callback use to give a status on asynchronous operation.

it returns a code and may return a string (could actually be empty) to detail what's happening callback is used on every operation possibly involving a connection to X3DH server: create_user, delete_user, encrypt and update

Parameters
[in]statussuccess or fail
[in]messagein case of failure, an explanation, it may be empty

◆ limeX3DHServerPostData

using lime::limeX3DHServerPostData = typedef std::function<void(const std::string &url, const std::string &from, const std::vector<uint8_t> &message, const limeX3DHServerResponseProcess &reponseProcess)>

Post a message to the X3DH server.

Parameters
[in]urlX3DH server's URL
[in]fromUser identification on X3DH server (which shall challenge for password digest, this is not however part of lime)
[in]messageThe message to post to the X3DH server
[in]responseProcessFunction to be called with server's response

◆ limeX3DHServerResponseProcess

using lime::limeX3DHServerResponseProcess = typedef std::function<void(int responseCode, const std::vector<uint8_t> &responseBody)>

Get the response from server. The external service providing secure communication to the X3DH server shall forward to lime library the server's response.

Parameters
[in]responseCodeLime expects communication with server to be over HTTPS, this shall be the response code. Lime expects 200 for successfull response from server. Any other response code is treated as an error and response ignored(but it is still usefull to forward it in order to perform internal cleaning)
[in]responseBodyThe actual response from X3DH server

◆ SharedADBuffer

using lime::SharedADBuffer = typedef std::array<uint8_t, lime::settings::DRSessionSharedADSize>

Shared Associated Data : stored at session initialisation, given by upper level(X3DH), shall be derived from Identity and Identity keys of sender and recipient, fixed size for storage convenience

Enumeration Type Documentation

◆ CallbackReturn

enum lime::CallbackReturn : uint8_t
strong

what a Lime callback could possibly say

Enumerator
success 

operation completed successfully

fail 

operation failed, we shall have an explanation string too

◆ CurveId

enum lime::CurveId : uint8_t
strong

Identifies the elliptic curve used in lime, the values assigned are used in localStorage and X3DH server so do not modify it or we'll loose sync with existing DB and X3DH server

Enumerator
unset 

used as default to detected incorrect behavior

c25519 

Curve 25519

c448 

Curve 448-goldilocks

◆ DRSessionDbStatus

enum lime::DRSessionDbStatus : uint8_t
strong

the possible status of session regarding the Local Storage

used to pick a subset of session to be saved in DB

Enumerator
clean 

session in cache match the one in local storage

dirty_encrypt 

an encrypt was performed modifying part of the cached session

dirty_decrypt 

a dencrypt was performed modifying part of the cached session

dirty_ratchet 

a ratchet step was performed modifying part of cached session

dirty 

the whole session data must be saved to local storage

◆ DSAtype

enum lime::DSAtype
strong

List of data types used by Signature algorithm.

public key, private key and signature

Enumerator
publicKey 
privateKey 
signature 

◆ EncryptionPolicy

Manage the encryption policy : how is the user's plaintext encrypted

Enumerator
DRMessage 

the plaintext input is encrypted inside the Double Ratchet message (each recipient get a different encryption): not optimal for messages with numerous recipient

cipherMessage 

the plaintext input is encrypted with a random key and this random key is encrypted to each participant inside the Double Ratchet message(for a single recipient the overhead is 48 bytes)

optimizeUploadSize 

optimize upload size: encrypt in DR message if plaintext is short enougth to beat the overhead introduced by cipher message scheme, otherwise use cipher message. Selection is made on upload size only. This is the default policy used

optimizeGlobalBandwidth 

optimize bandwith usage: encrypt in DR message if plaintext is short enougth to beat the overhead introduced by cipher message scheme, otherwise use cipher message. Selection is made on uploadand download (from server to recipients) sizes added.

◆ network_state

enum lime::network_state : uint8_t
strong
Enumerator
done 
sendSPk 
sendOPk 

◆ PeerDeviceStatus

enum lime::PeerDeviceStatus : uint8_t
strong

A peer device status returned after encrypt, decrypt or when directly asking for the peer device status to spot new devices and give information on our trust on this device The values explicitely mapped to specific integers(untrusted, trusted, unsafe) are stored in local storage as integer Do not modify the mapping or we will loose backward compatibility with existing databases

Enumerator
untrusted 

we know this device but do not trust it, that information shall be displayed to the end user, a colour code shall be enough

trusted 

this peer device already got its public identity key validated, that information shall be displayed to the end user too

unsafe 

this status is a helper for the library user. It is used only by the peerDeviceStatus accessor functions

fail 

when returned by decrypt : we could not decrypt the incoming message
when returned by encrypt in the peerStatus: we could not encrypt to this recipient(probably because it does not published keys on the X3DH server)

unknown 

when returned after encryption or decryption, means it is the first time we communicate with this device (and thus create a DR session with it)
when returned by a get_peerDeviceStatus: this device is not in localStorage

◆ X3DHKeyBundleFlag

enum lime::X3DHKeyBundleFlag : uint8_t
strong

Set possible values for a flag in the keyBundle X3DH packet.

Note
Do not modify values or we'll loose sync with existing X3DH server
Enumerator
noOPk 

This bundle does not contain an OPk

OPk 

This bundle contains an OPk

noBundle 

◆ Xtype

enum lime::Xtype
strong

List of data types used by key Echange algorithm.

public key, private key and shared secret

Enumerator
publicKey 
privateKey 
sharedSecret 

Function Documentation

◆ AEAD_decrypt()

template<typename AEADAlgo >
bool lime::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.

Parameters
[in]keyEncryption key
[in]keySizeKey buffer length, it must match the selected AEAD scheme or an exception is generated
[in]IVBuffer holding the initialisation vector
[in]IVSizeInitialisation vector length in bytes
[in]cipherBuffer holding the data to be decrypted
[in]cipherSizeLength in bytes of buffer to be decrypted
[in]ADBuffer holding additional data to be used in tag computation
[in]ADSizeAdditional data length in bytes
[in]tagBuffer holding the authentication tag
[in]tagSizeLength for the generated tag, it must match the selected AEAD scheme or an exception is generated
[out]plainbuffer holding the plain output, shall be at least the length of plainText buffer
Returns
true if authentication tag match and decryption was successful

◆ AEAD_decrypt< AES256GCM >()

template<>
bool lime::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 
)

◆ AEAD_encrypt()

template<typename AEADAlgo >
void lime::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.

Parameters
[in]keyEncryption key
[in]keySizeKey buffer length, it must match the selected AEAD scheme or an exception is generated
[in]IVBuffer holding the initialisation vector
[in]IVSizeInitialisation vector length in bytes
[in]plainbuffer to be encrypted
[in]plainSizeLength in bytes of buffer to be encrypted
[in]ADBuffer holding additional data to be used in tag computation
[in]ADSizeAdditional data length in bytes
[out]tagBuffer holding the generated tag
[in]tagSizeRequested length for the generated tag, it must match the selected AEAD scheme or an exception is generated
[out]cipherBuffer holding the output, shall be at least the length of plainText buffer

◆ AEAD_encrypt< AES256GCM >()

template<>
void lime::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 
)

◆ bctbx_ECDHInit()

template<typename Curve >
bctbx_ECDHContext_t* lime::bctbx_ECDHInit ( void  )

◆ bctbx_EDDSAInit()

template<typename Curve >
bctbx_EDDSAContext_t* lime::bctbx_EDDSAInit ( void  )

◆ cleanBuffer()

void lime::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

Parameters
[in,out]bufferthe buffer to be cleared
[in]sizebuffer size

◆ decrypt() [1/2]

static bool lime::decrypt ( const lime::DRMKey MK,
const std::vector< uint8_t > &  ciphertext,
const size_t  headerSize,
std::vector< uint8_t > &  AD,
std::vector< uint8_t > &  plaintext 
)
static

Decrypt as described is spec section 3.1.

Parameters
[in]MKA buffer holding key<32 bytes> || IV<16 bytes>
[in]ciphertextbuffer holding: header<size depends on Curve type> || ciphertext || auth tag<16 bytes>
[in]headerSizeSize of the header included in ciphertext
[in]ADAssociated data
[out]plaintextthe output message : a vector resized to hold the plaintext.
Returns
false if authentication failed

◆ decrypt() [2/2]

static bool lime::decrypt ( const lime::DRMKey MK,
const std::vector< uint8_t > &  ciphertext,
const size_t  headerSize,
std::vector< uint8_t > &  AD,
sBuffer< lime::settings::DRrandomSeedSize > &  plaintext 
)
static

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

used when the ouput is a fixed buffer: we decrypt the random seed used to generate the cipherMessage keys No need to resize the plaintext buffer when it has a fixed size.

◆ decryptMessage()

template<typename Curve >
std::shared_ptr< DR< Curve > > lime::decryptMessage ( const std::string &  sourceDeviceId,
const std::string &  recipientDeviceId,
const std::string &  recipientUserId,
std::vector< std::shared_ptr< DR< Curve >>> &  DRSessions,
const std::vector< uint8_t > &  DRmessage,
const std::vector< uint8_t > &  cipherMessage,
std::vector< uint8_t > &  plaintext 
)

Decrypt a message.

Decrypts the DR message and if applicable and the DR message was successfully decrypted, decrypt the cipherMessage

Parameters
[in]sourceDeviceIdthe device Id of sender(gruu)
[in]recipientDeviceIdthe recipient ID, specific to current device(gruu)
[in]recipientUserIdthe recipient ID, not specific to a device(could be a sip-uri) or a user(could be a group sip-uri)
[in,out]DRSessionslist of DR Sessions linked to sender device, first one shall be the one registered as active
[out]DRmessageDouble Ratcher message holding as payload either the encrypted plaintext or the random key used to encrypt it encrypted by the DR session
[out]cipherMessageif not zero lenght, plain text encrypted with a random generated key(and IV)
[out]plaintextdecrypted message
Returns
a shared pointer towards the session used to decrypt, nullptr if we couldn't find one to do it

◆ encryptMessage()

template<typename Curve >
void lime::encryptMessage ( std::vector< RecipientInfos< Curve >> &  recipients,
const std::vector< uint8_t > &  plaintext,
const std::string &  recipientUserId,
const std::string &  sourceDeviceId,
std::vector< uint8_t > &  cipherMessage,
const lime::EncryptionPolicy  encryptionPolicy 
)

Encrypt a message to all recipients, identified by their device id.

The plaintext is first encrypted by one randomly generated key using aes-gcm The key and IV are then encrypted with DR Session specific to each device

Parameters
[in,out]recipientsvector of recipients device id(gruu) and linked DR Session, DR Session are modified by the encryption
The recipients struct also hold after encryption the double ratchet message targeted to that particular recipient
[in]plaintextdata to be encrypted
[in]recipientUserIdthe recipient ID, not specific to a device(could be a sip-uri) or a user(could be a group sip-uri)
[in]sourceDeviceIdthe Id of sender device(gruu)
[out]cipherMessagemessage encrypted with a random generated key(and IV). May be an empty buffer depending on encryptionPolicy, recipients and plaintext characteristics
[in]encryptionPolicyselect how to manage the encryption: direct use of Double Ratchet message or encrypt in the cipher message and use the DR message to share the cipher message key
default is optimized output size mode.

◆ HMAC()

template<typename hashAlgo >
void lime::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

Template Parameters
hashAlgothe hash algorithm used (only SHA512 available for now)
Parameters
[in]keyHMAC key
[in]keySizeprevious buffer size
[in]inputHMAC input
[in]inputSizeprevious buffer size
[out]hashpointer to the output, this buffer must be able to hold as much data as requested
[in]hashSizeamount of expected data, if more than selected Hash algorithm can compute, silently ignored and maximum output size is generated

◆ HMAC< SHA512 >()

template<>
void lime::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 
)

◆ HMAC_KDF() [1/2]

template<typename hashAlgo , typename infoType >
void lime::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 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. use pointer to uint8_t and size arguments instead of std::vector<uint8_t>

◆ HMAC_KDF() [2/2]

template<typename hashAlgo , typename infoType >
void lime::HMAC_KDF ( const std::vector< uint8_t > &  salt,
const std::vector< uint8_t > &  ikm,
const infoType &  info,
uint8_t *  okm,
size_t  okmSize 
)

HKDF as described in RFC5869.

Compute:
PRK = HMAC-Hash(salt, IKM)
N = ceil(L/HashLen)
T = T(1) | T(2) | T(3) | ... | T(N)
OKM = first L octets of T
where:
T(0) = empty string (zero length)
T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
...
Template Parameters
hashAlgothe hash algorithm to use (SHA512 available for now)
infoTypethe info parameter can be passed as a string or a std::vector<uint8_t>
Parameters
[in]saltsalt
[in]ikminput key material
[in]infoa info string or buffer
[out]okmoutput key material
[in]okmSizerequested amount of data, okm buffer must be able to hold it. (L in the RFC doc)

◆ HMAC_KDF< SHA512, std::string >() [1/2]

template void lime::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 
)

◆ HMAC_KDF< SHA512, std::string >() [2/2]

template void lime::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 
)

◆ HMAC_KDF< SHA512, std::vector< uint8_t > >() [1/2]

template void lime::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 
)

◆ HMAC_KDF< SHA512, std::vector< uint8_t > >() [2/2]

template void lime::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 
)

◆ insert_LimeUser()

std::shared_ptr< LimeGeneric > lime::insert_LimeUser ( const std::string &  dbFilename,
const std::string &  deviceId,
const std::string &  url,
const lime::CurveId  curve,
const uint16_t  OPkInitialBatchSize,
const limeX3DHServerPostData X3DH_post_data,
const limeCallback callback,
std::shared_ptr< std::recursive_mutex >  db_mutex 
)

: Insert user in database and return a pointer to the control class instanciating the appropriate Lime children class

Once created a user cannot be modified, insertion of existing deviceId will raise an exception.

Parameters
[in]dbFilenamePath to filename to use
[in]deviceIdUser to create in DB, deviceId shall be the GRUU
[in]urlURL of X3DH key server to be used to publish our keys
[in]curveWhich curve shall we use for this account, select the implemenation to instanciate when using this user
[in]OPkInitialBatchSizeNumber of OPks in the first batch uploaded to X3DH server
[in]X3DH_post_dataA function used to communicate with the X3DH server
[in]callbackTo provide caller the operation result
[in]db_mutexa mutex to protect db access
Returns
a pointer to the LimeGeneric class allowing access to API declared in lime_lime.hpp

◆ KDF_CK()

static void lime::KDF_CK ( DRChainKey CK,
DRMKey MK 
)
staticnoexcept

Key Derivation Function used in Symmetric key ratchet chain.

Implemented according to Double Ratchet spec section 5.2 using HMAC-SHA512

MK = HMAC-SHA512(CK, hkdf_mk_info) // get 48 bytes of it: first 32 to be key and last 16 to be IV
CK = HMAC-SHA512(CK, hkdf_ck_info)
hkdf_ck_info and hldf_mk_info being a distincts constants (0x02 and 0x01 as suggested in double ratchet - section 5.2)
Parameters
[in,out]CKInput/output buffer used as key to compute MK and then next CK
[out]MKMessage Key(32 bytes) and IV(16 bytes) computed from HMAC_SHA512 keyed with CK

◆ KDF_RK()

template<typename Curve >
static void lime::KDF_RK ( DRChainKey RK,
DRChainKey CK,
const X< Curve, lime::Xtype::sharedSecret > &  dh_out 
)
staticnoexcept

Key Derivation Function used in Root key/Diffie-Hellman Ratchet chain.

Use HKDF (see RFC5869) to derive CK and RK in one derivation

Parameters
[in,out]RKInput buffer used as salt also to store the 32 first byte of output key material
[out]CKOutput buffer, last 32 bytes of output key material
[in]dh_outBuffer used as input key material

◆ load_LimeUser()

std::shared_ptr< LimeGeneric > lime::load_LimeUser ( const std::string &  dbFilename,
const std::string &  deviceId,
const limeX3DHServerPostData X3DH_post_data,
std::shared_ptr< std::recursive_mutex >  db_mutex,
const bool  allStatus 
)

: Load user from database and return a pointer to the control class instanciating the appropriate Lime children class

Fail to find the user will raise an exception If allStatus flag is set to false (default value), raise an exception on inactive users otherwise load inactive user.

Parameters
[in]dbFilenamePath to filename to use
[in]deviceIdUser to lookup in DB, deviceId shall be the GRUU
[in]X3DH_post_dataA function used to communicate with the X3DH server
[in]db_mutexa mutex to protect db access
[in]allStatusallow loading of inactive user if set to true
Returns
a pointer to the LimeGeneric class allowing access to API declared in lime_lime.hpp

◆ make_keyExchange()

template<typename Curve >
std::shared_ptr< keyExchange< Curve > > lime::make_keyExchange ( )

◆ make_RNG()

std::shared_ptr< RNG > lime::make_RNG ( )

◆ make_Signature()

template<typename Curve >
std::shared_ptr< Signature< Curve > > lime::make_Signature ( )

Variable Documentation

◆ hkdf_ck_info

const std::array<std::uint8_t,1> lime::hkdf_ck_info {{0x02}}

constant used as input of HKDF like function, see double ratchet spec section 5.2 - KDF_CK

◆ hkdf_mk_info

const std::array<std::uint8_t,1> lime::hkdf_mk_info {{0x01}}

constant used as input of HKDF like function, see double ratchet spec section 5.2 - KDF_CK