lime
Lime is a C++ library implementing Open Whisper System Signal protocol
Classes | Typedefs | Enumerations | Functions | Variables
lime::anonymous_namespace{lime_double_ratchet.cpp} Namespace Reference

Classes

class  DRHeader
 helper class and functions to parse Double Ratchet message header and access its components More...
 
class  DRHeader< Algo, true >
 
class  DRHeader< Curve, false >
 
struct  ReceiverKeyChain
 Chain storing the DH and MKs associated with Nr(uint16_t map index) More...
 

Typedefs

using DRMKey = lime::sBuffer< lime::settings::DRMessageKeySize+lime::settings::DRMessageIVSize >
 

Enumerations

enum  DRSessionDbStatus : uint8_t {
  DRSessionDbStatus::clean, DRSessionDbStatus::dirty_encrypt, DRSessionDbStatus::dirty_decrypt, DRSessionDbStatus::dirty_ratchet_receiving,
  DRSessionDbStatus::dirty_kem_ratchet_receiving, DRSessionDbStatus::dirty_ratchet_sending, DRSessionDbStatus::dirty
}
 the possible status of session regarding the Local Storage More...
 
enum  DHrStatusBitMap : uint32_t {
  DHrStatusBitMap::forceKEMRatchet = 0x00000001, DHrStatusBitMap::peerKEMPkAvailable = 0x00000002, DHrStatusBitMap::peerHasSelfKEMPk = 0x00000004, DHrStatusBitMap::peerECPkAvailable = 0x00000008,
  DHrStatusBitMap::KEMRatchetChainSize = 0x7FFFFF00
}
 

Functions

template<typename Curve >
static void KDF_RK (DRChainKey &RK, DRChainKey &CK, const X< Curve, lime::Xtype::sharedSecret > &dhOut) noexcept
 Key Derivation Function used in Root key/Diffie-Hellman Ratchet chain. More...
 
template<typename Curve >
static void KEM_KDF_RK (DRChainKey &RK, DRChainKey &CK, const X< typename Curve::EC, lime::Xtype::sharedSecret > &dhOut, const K< typename Curve::KEM, lime::Ktype::sharedSecret > &kemOut, const X< typename Curve::EC, lime::Xtype::publicKey > &ECPkSender, const X< typename Curve::EC, lime::Xtype::publicKey > &ECPkReceiver, const K< typename Curve::KEM, lime::Ktype::publicKey > &KEMPk, const K< typename Curve::KEM, lime::Ktype::cipherText > &KEMCt) noexcept
 Key Derivation Function used in Root key/Diffie-Hellman/KEM Ratchet chain. More...
 
template<typename Curve >
static void KDF_CK (DRChainKey &CK, DRMKey &MK, uint16_t chainIndex, typename std::enable_if_t<!std::is_base_of_v< genericKEM, Curve >, bool >=true) noexcept
 Key Derivation Function used in Symmetric key ratchet chain. More...
 
template<typename Curve >
static void KDF_CK (DRChainKey &CK, DRMKey &MK, uint16_t chainIndex, typename std::enable_if_t< std::is_base_of_v< genericKEM, Curve >, bool >=true) noexcept
 
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...
 

Variables

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

Detailed Description

Status on peer's public key in the DR session, as stored in DB in a 4 bytes integer mapping: byte 3 | byte 2 | byte 1 | byte 0 <Total number of message sent/received - or skipped -since last KEM ratchet> Flags as detailed below The total number of message should never increase more than maxKEMRatchetChainSize the peer in position of performing a KEM ratchet is encrypting message or maxSendingChain if he is not.

Flags bitmap : – 0 force KEM ratchet ASAP (set when a session is created on receiver side to force KEM ratchet at first response) – 1 KEM peer pk available locally – 2 KEM self pk known by peer – 3 EC peer pk available locally

Typedef Documentation

using lime::anonymous_namespace{lime_double_ratchet.cpp}::DRMKey = typedef lime::sBuffer<lime::settings::DRMessageKeySize+lime::settings::DRMessageIVSize>

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

Enumeration Type Documentation

enum lime::anonymous_namespace{lime_double_ratchet.cpp}::DHrStatusBitMap : uint32_t
strong
Enumerator
forceKEMRatchet 
peerKEMPkAvailable 
peerHasSelfKEMPk 
peerECPkAvailable 
KEMRatchetChainSize 
enum lime::anonymous_namespace{lime_double_ratchet.cpp}::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_receiving 

a EC onlyratchet step was performed modifying part of cached session, using a new peer pk

dirty_kem_ratchet_receiving 

a KEM/EC ratchet step was performed modifying part of cached session, using a new peer pk

dirty_ratchet_sending 

a ratchet step was performed modifying part of cached session, using a new self pk

dirty 

the whole session data must be saved to local storage

Function Documentation

static bool lime::anonymous_namespace{lime_double_ratchet.cpp}::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
template<typename Curve >
static void lime::anonymous_namespace{lime_double_ratchet.cpp}::KDF_CK ( DRChainKey CK,
DRMKey MK,
uint16_t  chainIndex,
typename std::enable_if_t<!std::is_base_of_v< genericKEM, Curve >, bool >  = true 
)
staticnoexcept

Key Derivation Function used in Symmetric key ratchet chain.

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

1 MK = HMAC-SHA512(CK, hkdf_mk_info) // get 48 bytes of it: first 32 to be key and last 16 to be IV
2 CK = HMAC-SHA512(CK, hkdf_ck_info)
3  hkdf_ck_info and hkdf_mk_info being a distincts constants (0x02 and 0x01 as suggested in double ratchet - section 5.2)

The EC/KEM version includes a modification from https://eprint.iacr.org/2024/220.pdf section 4.2: use the chain index in the derivation append the derivation index to hkdf_mk_info and hkdf_ck_info

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
template<typename Curve >
static void lime::anonymous_namespace{lime_double_ratchet.cpp}::KDF_CK ( DRChainKey CK,
DRMKey MK,
uint16_t  chainIndex,
typename std::enable_if_t< std::is_base_of_v< genericKEM, Curve >, bool >  = true 
)
staticnoexcept
template<typename Curve >
static void lime::anonymous_namespace{lime_double_ratchet.cpp}::KDF_RK ( DRChainKey RK,
DRChainKey CK,
const X< Curve, lime::Xtype::sharedSecret > &  dhOut 
)
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]dhOutBuffer used as input key material
template<typename Curve >
static void lime::anonymous_namespace{lime_double_ratchet.cpp}::KEM_KDF_RK ( DRChainKey RK,
DRChainKey CK,
const X< typename Curve::EC, lime::Xtype::sharedSecret > &  dhOut,
const K< typename Curve::KEM, lime::Ktype::sharedSecret > &  kemOut,
const X< typename Curve::EC, lime::Xtype::publicKey > &  ECPkSender,
const X< typename Curve::EC, lime::Xtype::publicKey > &  ECPkReceiver,
const K< typename Curve::KEM, lime::Ktype::publicKey > &  KEMPk,
const K< typename Curve::KEM, lime::Ktype::cipherText > &  KEMCt 
)
staticnoexcept

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

Use HKDF (see RFC5869) to derive CK and RK in one derivation The key derivation uses as input material the DH and KEM shared secrets but also a transcript of all public material used to compute them

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]dhOutBuffer used as input key material
[in]kemOutBuffer used as input key material
[in]ECPkSenderEC Public Key Sender
[in]ECPkReceiverEC Public Key Receiver
[in]KEMPkKEM public key
[in]KEMCtKEM cipher text

Variable Documentation

const std::array<uint8_t,1> lime::anonymous_namespace{lime_double_ratchet.cpp}::hkdf_ck_info {{0x02}}

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

const std::array<uint8_t,1> lime::anonymous_namespace{lime_double_ratchet.cpp}::hkdf_mk_info {{0x01}}

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