Commit a34d95c3 authored by johan's avatar johan
Browse files

Improve code documentation

+minor refactoring on recipientInfos struct in lime_double_ratchet.hpp
parent ef54abe5
......@@ -406,7 +406,7 @@ LOOKUP_CACHE_SIZE = 0
# normally produced when WARNINGS is set to YES.
# The default value is: NO.
EXTRACT_ALL = NO
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
# be included in the documentation.
......@@ -424,7 +424,7 @@ EXTRACT_PACKAGE = NO
# included in the documentation.
# The default value is: NO.
EXTRACT_STATIC = NO
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO
......
......@@ -33,7 +33,8 @@ namespace lime {
enum class CurveId : uint8_t {
unset=0, /**< used as default to detected incorrect behavior */
c25519=1, /**< Curve 25519 */
c448=2}; /**< Curve 448-goldilocks */
c448=2 /**< Curve 448-goldilocks */
};
/** Manage the encryption policy : how is the user's plaintext encrypted */
enum class EncryptionPolicy {
......@@ -52,16 +53,23 @@ namespace lime {
untrusted=0, /**< 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=1, /**< this peer device already got its public identity key validated, that information shall be displayed to the end user too */
unsafe=2, /**< 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),
fail, /**< when returned by decrypt : we could not decrypt the incoming message\n
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)\n
when returned by a get_peerDeviceStatus: this device is not in localStorage */
};
/** Used to manage recipient list for encrypt function input: give a recipient GRUU and get it back with the header which must be sent to recipient with the cipher text*/
/** @brief The encrypt function input/output data structure
*
* give a recipient GRUU and get it back with the header which must be sent to recipient with the cipher text
*/
struct RecipientData {
const std::string deviceId; /**< input: recipient deviceId (shall be GRUU) */
lime::PeerDeviceStatus peerStatus; /**< output: after encrypt calls back, it will hold the status of this peer device: unknown (first interaction with this device), untrusted or trusted */
lime::PeerDeviceStatus peerStatus; /**< output: after encrypt calls back, it will hold the status of this peer device:\n
- unknown: first interaction with this device)
- untrusted: device is kown but we never confirmed its identity public key
- trusted: we already confirmed this device identity public key
- fail: we could not encrypt for this device, probably because it never published its keys on the X3DH server */
std::vector<uint8_t> DRmessage; /**< output: after encrypt calls back, it will hold the Double Ratchet message targeted to the specified recipient. */
/**
* recipient data are built giving a recipient id
......@@ -76,6 +84,7 @@ namespace lime {
fail /**< operation failed, we shall have an explanation string too */
};
/** @brief 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
* @param[in] status success or fail
......@@ -106,7 +115,8 @@ namespace lime {
/* Forward declare the class managing one lime user*/
class LimeGeneric;
/** Manage Lime objects
/** @brief Manage several Lime objects(one is needed for each local user).
*
* LimeManager is mostly a cache of Lime users, any command get as first parameter the device Id (Lime manage devices only, the link user(sip:uri)<->device(GRUU) is provided by upper level)
* All interactions should take place through the LimeManager object, any endpoint shall have only one LimeManager object instanciated
*/
......@@ -122,6 +132,7 @@ namespace lime {
/**
* @brief Create a user in local database and publish it on the given X3DH server
*
* The Lime user shall be created at the same time the account is created on the device, this function shall not be called again, attempt to re-create an already existing user will fail.
* A user is identified by its deviceId (shall be the GRUU) and must at creation select a base Elliptic curve to use, this setting cannot be changed later
* A user is published on an X3DH key server who must run using the same elliptic curve selected for this user (creation will fail otherwise), the server url cannot be changed later
......@@ -129,14 +140,14 @@ namespace lime {
* @param[in] localDeviceId Identify the local user acount to use, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU
* @param[in] x3dhServerUrl The complete url(including port) of the X3DH key server. It must connect using HTTPS. Example: https://sip5.linphone.org:25519
* @param[in] curve Choice of elliptic curve to use as base for ECDH and EdDSA operation involved. Can be CurveId::c25519 or CurveId::c448.
* @param[in] initialOPkBatchSize Number of OPks in the first batch uploaded to X3DH server
* @param[in] OPkInitialBatchSize Number of OPks in the first batch uploaded to X3DH server
* @param[in] callback This operation contact the X3DH server and is thus asynchronous, when server responds,
* this callback will be called giving the exit status and an error message in case of failure
* @note
* The initialOPkBatchSize is optionnal, if not used, set to defaults defined in lime::settings
* The OPkInitialBatchSize is optionnal, if not used, set to defaults defined in lime::settings
* (not done with param default value as the lime::settings shall not be available in public include)
*/
void create_user(const std::string &localDeviceId, const std::string &x3dhServerUrl, const lime::CurveId curve, const uint16_t initialOPkBatchSize, const limeCallback &callback);
void create_user(const std::string &localDeviceId, const std::string &x3dhServerUrl, const lime::CurveId curve, const uint16_t OPkInitialBatchSize, const limeCallback &callback);
/**
* @overload void create_user(const std::string &localDeviceId, const std::string &x3dhServerUrl, const lime::CurveId curve, const limeCallback &callback)
*/
......@@ -144,6 +155,7 @@ namespace lime {
/**
* @brief Delete a user from local database and from the X3DH server
*
* if specified localDeviceId is not found in local Storage, throw an exception
*
* @param[in] localDeviceId Identify the local user acount to use, it must be unique and is also be used as Id on the X3DH key server, it shall be the GRUU
......@@ -154,6 +166,7 @@ namespace lime {
/**
* @brief Encrypt a buffer (text or file) for a given list of recipient devices
*
* if specified localDeviceId is not found in local Storage, throw an exception
*
* Clarification on recipients:
......@@ -181,7 +194,7 @@ namespace lime {
* @param[in,out] recipients a list of RecipientData holding:
* - the recipient device Id(GRUU)
* - an empty buffer to store the DRmessage which must then be routed to that recipient
* - the peer Status. If peerStatus is set to fail, this entry is ignored otherwise the peerStatus is set by the encrypt, see PeerDeviceStatus definition for details
* - the peer Status. If peerStatus is set to fail, this entry is ignored otherwise the peerStatus is set by the encrypt, see ::PeerDeviceStatus definition for details
* @param[in] plainMessage a buffer holding the message to encrypt, can be text or data.
* @param[out] cipherMessage points to the buffer to store the encrypted message which must be routed to all recipients(if one is produced, depends on encryption policy)
* @param[in] callback Performing encryption may involve the X3DH server and is thus asynchronous, when the operation is completed,
......@@ -195,6 +208,7 @@ namespace lime {
/**
* @brief Decrypt the given message
*
* if specified localDeviceId is not found in local Storage, throw an exception
*
* @param[in] localDeviceId used to identify which local acount to use and also as the recipient device ID of the message, shall be the GRUU
......@@ -216,6 +230,7 @@ namespace lime {
/**
* @brief Update: shall be called once a day at least, performs checks, updates and cleaning operations
*
* - check if we shall update a new SPk to X3DH server(SPk lifetime is set in settings)
* - check if we need to upload OPks to X3DH server
* - remove old SPks, clean double ratchet sessions (remove staled, clean their stored keys for skipped messages)
......@@ -239,6 +254,7 @@ namespace lime {
/**
* @brief retrieve self Identity Key, an EdDSA formatted public key
*
* if specified localDeviceId is not found in local Storage, throw an exception
*
*
......@@ -279,6 +295,7 @@ namespace lime {
/**
* @brief set the peer device status flag in local storage: unsafe or untrusted.
*
* This variation allows to set a peer Device status to unsafe or untrusted only whithout providing its identity key Ik
*
* @param[in] peerDeviceId The device Id of peer, shall be its GRUU
......
......@@ -28,13 +28,6 @@ using namespace::std;
namespace lime {
/****************************************************************************/
/* */
/* Members helpers functions (privates) */
/* */
/****************************************************************************/
/****************************************************************************/
/* */
/* Constructors */
......@@ -42,6 +35,7 @@ namespace lime {
/****************************************************************************/
/**
* @brief Load user constructor
*
* before calling this constructor, user existence in DB is checked and its Uid retrieved
* just load it into Lime class
*
......@@ -50,6 +44,8 @@ namespace lime {
* @param[in] url URL of the X3DH key server used to publish our keys(retrieved from DB)
* @param[in] X3DH_post_data A function used to communicate with the X3DH server
* @param[in] Uid the DB internal Id for this user, speed up DB operations by holding it in DB
*
* @note: ownership of localStorage pointer is transfered to a shared pointer, private menber of Lime class
*/
template <typename Curve>
Lime<Curve>::Lime(std::unique_ptr<lime::Db> &&localStorage, const std::string &deviceId, const std::string &url, const limeX3DHServerPostData &X3DH_post_data, const long int Uid)
......@@ -63,12 +59,15 @@ namespace lime {
/**
* @brief Create user constructor
* Create a user in DB, if already existing, throw exception
*
* Create a user in DB, if already existing, throw an exception
*
* @param[in,out] localStorage pointer to DB accessor
* @param[in] deviceId device Id(shall be GRUU), stored in the structure
* @param[in] url URL of the X3DH key server used to publish our keys
* @param[in] X3DH_post_data A function used to communicate with the X3DH server
*
* @note: ownership of localStorage pointer is transfered to a shared pointer, private menber of Lime class
*/
template <typename Curve>
Lime<Curve>::Lime(std::unique_ptr<lime::Db> &&localStorage, const std::string &deviceId, const std::string &url, const limeX3DHServerPostData &X3DH_post_data)
......@@ -86,16 +85,10 @@ namespace lime {
/****************************************************************************/
/* */
/* Public API */
/* Public API implenenting the virtual class LimeGeneric */
/* API documentation is in lime_lime.hpp */
/* */
/****************************************************************************/
/**
* @brief Publish on X3DH server the user, it is performed just after creation in local storage
* this will, on success, trigger generation and sending of SPk and OPks for our new user
*
* @param[in] callback call when completed
* @param[in] OPkInitialBatchSize Number of OPks in the first batch uploaded to X3DH server
*/
template <typename Curve>
void Lime<Curve>::publish_user(const limeCallback &callback, const uint16_t OPkInitialBatchSize) {
auto userData = make_shared<callbackUserData<Curve>>(this->shared_from_this(), callback, OPkInitialBatchSize, true);
......@@ -299,17 +292,18 @@ namespace lime {
/****************************************************************************/
/**
* @brief : 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.
*
* @param[in] dbFilename Path to filename to use
* @param[in] deviceId User to create in DB, deviceId shall be the GRUU
* @param[in] url URL of X3DH key server to be used to publish our keys
* @param[in] curve Which curve shall we use for this account, select the implemenation to instanciate when using this user
* @param[in] initialOPkBatchSize Number of OPks in the first batch uploaded to X3DH server
* @param[in] OPkInitialBatchSize Number of OPks in the first batch uploaded to X3DH server
* @param[in] X3DH_post_data A function used to communicate with the X3DH server
* @param[in] callback To provide caller the operation result
*
* @return a pointer to the LimeGeneric class allowing access to API declared in lime.hpp
* @return a pointer to the LimeGeneric class allowing access to API declared in lime_lime.hpp
*/
std::shared_ptr<LimeGeneric> 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) {
......@@ -366,13 +360,14 @@ namespace lime {
/**
* @brief : 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
*
* @param[in] dbFilename Path to filename to use
* @param[in] deviceId User to lookup in DB, deviceId shall be the GRUU
* @param[in] X3DH_post_data A function used to communicate with the X3DH server
*
* @return a pointer to the LimeGeneric class allowing access to API declared in lime.hpp
* @return a pointer to the LimeGeneric class allowing access to API declared in lime_lime.hpp
*/
std::shared_ptr<LimeGeneric> load_LimeUser(const std::string &dbFilename, const std::string &deviceId, const limeX3DHServerPostData &X3DH_post_data) {
......
......@@ -48,7 +48,7 @@ namespace lime {
/***** Random Number Generator ********/
/**
* A wrapper around the bctoolbox Random Number Generator
* @brief A wrapper around the bctoolbox Random Number Generator, implements the RNG interface
*/
class bctbx_RNG : public RNG {
private :
......@@ -70,27 +70,16 @@ class bctbx_RNG : public RNG {
public:
/* accessor */
/**
* @brief fill the given RandomSeed buffer with Random bytes
*
* @param[in,out] buffer point to the beginning of the buffer to be filled with random bytes
*/
void randomize(sBuffer<lime::settings::DRrandomSeedSize> &buffer) override {
bctbx_rng_get(m_context, buffer.data(), buffer.size());
};
/**
* @brief Generate a 32 bits unsigned integer(used to generate keys Id)
* The MSbit is forced to 0 to avoid dealing with DB misinterpreting unsigned values into signed one
* Our random number is actually on 31 bits.
*
* @return a random 32 bits unsigned integer
*/
uint32_t randomize() override {
std::array<uint8_t, 4> buffer;
bctbx_rng_get(m_context, buffer.data(), buffer.size());
buffer[0] = 0; // just to be sure it's properly set to 0
// buffer[0] is shifted by 23 instead of 24 to keep the MSb to 0.
// as we must (see RNG interface definition) keep the uint32_t MSb set to 0
return (static_cast<uint32_t>(buffer[0])<<23 | static_cast<uint32_t>(buffer[1])<<16 | static_cast<uint32_t>(buffer[2])<<8 | static_cast<uint32_t>(buffer[3]));
};
......@@ -132,7 +121,8 @@ bctbx_EDDSAContext_t *bctbx_EDDSAInit(void) {
#endif // EC448_ENABLED
/**
* a wrapper around bctoolbox Signature algorithm.
* @brief a wrapper around bctoolbox signature algorithms, implements the Signature interface
*
* Provides EdDSA on curves 25519 and 448
*/
template <typename Curve>
......@@ -141,7 +131,7 @@ class bctbx_EDDSA : public Signature<Curve> {
bctbx_EDDSAContext_t *m_context; // the EDDSA context
public :
/* accessors */
const DSA<Curve, lime::DSAtype::privateKey> get_secret(void) override { /**< Secret key */
const DSA<Curve, lime::DSAtype::privateKey> get_secret(void) override {
if (m_context->secretKey == nullptr) {
throw BCTBX_EXCEPTION << "invalid EdDSA secret key";
}
......@@ -152,7 +142,7 @@ class bctbx_EDDSA : public Signature<Curve> {
std::copy_n(m_context->secretKey, s.ssize(), s.data());
return s;
}
const DSA<Curve, lime::DSAtype::publicKey> get_public(void) override {/**< Self Public key */
const DSA<Curve, lime::DSAtype::publicKey> get_public(void) override {
if (m_context->publicKey == nullptr) {
throw BCTBX_EXCEPTION << "invalid EdDSA public key";
}
......@@ -165,72 +155,41 @@ class bctbx_EDDSA : public Signature<Curve> {
}
/* Setting keys */
void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secretKey) override { /**< Secret key */
void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secretKey) override {
bctbx_EDDSA_setSecretKey(m_context, secretKey.data(), secretKey.ssize());
}
void set_public(const DSA<Curve, lime::DSAtype::publicKey> &publicKey) override { /**< Self Public key */
void set_public(const DSA<Curve, lime::DSAtype::publicKey> &publicKey) override {
bctbx_EDDSA_setPublicKey(m_context, publicKey.data(), publicKey.ssize());
}
/**
* @brief generate a new random EdDSA key pair
*
* @param[in] rng The Random Number Generator to be used to generate the private kay
*/
void createKeyPair(std::shared_ptr<lime::RNG> rng) override {
// the dynamic cast will generate an exception if RNG is not actually a bctbx_RNG
bctbx_EDDSACreateKeyPair(m_context, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, dynamic_cast<lime::bctbx_RNG&>(*rng).get_context());
}
/**
* @brief Compute the public key using the secret already set in context
*/
void derivePublic(void) override {
bctbx_EDDSADerivePublicKey(m_context);
}
/**
* @brief Sign a message using the key pair previously set in the object
*
* @param[in] message The message to be signed
* @param[out] signature The signature produced from the message with a key pair previously introduced in the object
*/
void sign(const std::vector<uint8_t> &message, DSA<Curve, lime::DSAtype::signature> &signature) override {
auto sigSize = signature.size();
bctbx_EDDSA_sign(m_context, message.data(), message.size(), nullptr, 0, signature.data(), &sigSize);
}
/**
* @overload void bctbx_EDDSA::sign(const X<Curve, lime::Xtype::publicKey> &message, DSA<Curve, lime::DSAtype::signature> &signature)
* a convenience function to directly verify a key exchange public key
*/
void sign(const X<Curve, lime::Xtype::publicKey> &message, DSA<Curve, lime::DSAtype::signature> &signature) override {
auto sigSize = signature.size();
bctbx_EDDSA_sign(m_context, message.data(), message.ssize(), nullptr, 0, signature.data(), &sigSize);
}
/**
* @brief Verify a message signature using the public key previously set in the object
*
* @param[in] message The message signed
* @param[in] signature The signature produced from the message with a key pair previously introduced in the object
*
* @return true if the signature is valid, false otherwise
*/
bool verify(const std::vector<uint8_t> &message, const DSA<Curve, lime::DSAtype::signature> &signature) override {
return (bctbx_EDDSA_verify(m_context, message.data(), message.size(), nullptr, 0, signature.data(), signature.size()) == BCTBX_VERIFY_SUCCESS);
}
/**
* @overload bool bctbx_EDDSA::verify(const X<Curve, lime::Xtype::publicKey> &message, const DSA<Curve, lime::DSAtype::signature> &signature)
* a convenience function to directly verify a key exchange public key
*/
bool verify(const X<Curve, lime::Xtype::publicKey> &message, const DSA<Curve, lime::DSAtype::signature> &signature) override {
return (bctbx_EDDSA_verify(m_context, message.data(), message.ssize(), nullptr, 0, signature.data(), signature.ssize()) == BCTBX_VERIFY_SUCCESS);
}
/**
* ctor/dtor
*/
bctbx_EDDSA() {
m_context = bctbx_EDDSAInit<Curve>();
}
......@@ -266,7 +225,8 @@ bctbx_ECDHContext_t *bctbx_ECDHInit(void) {
#endif //EC448_ENABLED
/**
* a wrapper around bctoolbox key exchange algorithm.
* @brief a wrapper around bctoolbox key exchange algorithms, implements the keyExchange interface
*
* Provides X25519 and X448
*/
template <typename Curve>
......@@ -275,7 +235,7 @@ class bctbx_ECDH : public keyExchange<Curve> {
bctbx_ECDHContext_t *m_context; // the ECDH context
public :
/* accessors */
const X<Curve, lime::Xtype::privateKey> get_secret(void) override { /**< Secret key */
const X<Curve, lime::Xtype::privateKey> get_secret(void) override {
if (m_context->secret == nullptr) {
throw BCTBX_EXCEPTION << "invalid ECDH secret key";
}
......@@ -286,7 +246,7 @@ class bctbx_ECDH : public keyExchange<Curve> {
std::copy_n(m_context->secret, s.ssize(), s.data());
return s;
}
const X<Curve, lime::Xtype::publicKey> get_selfPublic(void) override {/**< Self Public key */
const X<Curve, lime::Xtype::publicKey> get_selfPublic(void) override {
if (m_context->selfPublic == nullptr) {
throw BCTBX_EXCEPTION << "invalid ECDH self public key";
}
......@@ -297,7 +257,7 @@ class bctbx_ECDH : public keyExchange<Curve> {
std::copy_n(m_context->selfPublic, p.ssize(), p.data());
return p;
}
const X<Curve, lime::Xtype::publicKey> get_peerPublic(void) override { /**< Peer Public key */
const X<Curve, lime::Xtype::publicKey> get_peerPublic(void) override {
if (m_context->peerPublic == nullptr) {
throw BCTBX_EXCEPTION << "invalid ECDH peer public key";
}
......@@ -308,7 +268,7 @@ class bctbx_ECDH : public keyExchange<Curve> {
std::copy_n(m_context->peerPublic, p.ssize(), p.data());
return p;
}
const X<Curve, lime::Xtype::sharedSecret> get_sharedSecret(void) override { /**< ECDH output */
const X<Curve, lime::Xtype::sharedSecret> get_sharedSecret(void) override {
if (m_context->sharedSecret == nullptr) {
throw BCTBX_EXCEPTION << "invalid ECDH shared secret";
}
......@@ -322,11 +282,11 @@ class bctbx_ECDH : public keyExchange<Curve> {
/* Setting keys, accept Signature keys */
void set_secret(const X<Curve, lime::Xtype::privateKey> &secret) override { /**< Secret key */
void set_secret(const X<Curve, lime::Xtype::privateKey> &secret) override {
bctbx_ECDHSetSecretKey(m_context, secret.data(), secret.ssize());
}
void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secret) override { /**< Secret key */
void set_secret(const DSA<Curve, lime::DSAtype::privateKey> &secret) override {
// we must create a temporary bctbx_EDDSA context and set the given key in
auto tmp_context = bctbx_EDDSAInit<Curve>();
bctbx_EDDSA_setSecretKey(tmp_context, secret.data(), secret.ssize());
......@@ -338,11 +298,11 @@ class bctbx_ECDH : public keyExchange<Curve> {
bctbx_DestroyEDDSAContext(tmp_context);
}
void set_selfPublic(const X<Curve, lime::Xtype::publicKey> &selfPublic) override { /**< Self Public key */
void set_selfPublic(const X<Curve, lime::Xtype::publicKey> &selfPublic) override {
bctbx_ECDHSetSelfPublicKey(m_context, selfPublic.data(), selfPublic.ssize());
}
void set_selfPublic(const DSA<Curve, lime::DSAtype::publicKey> &selfPublic) override { /**< Self Public key */
void set_selfPublic(const DSA<Curve, lime::DSAtype::publicKey> &selfPublic) override {
// we must create a temporary bctbx_EDDSA context and set the given key in
auto tmp_context = bctbx_EDDSAInit<Curve>();
bctbx_EDDSA_setPublicKey(tmp_context, selfPublic.data(), selfPublic.ssize());
......@@ -354,11 +314,11 @@ class bctbx_ECDH : public keyExchange<Curve> {
bctbx_DestroyEDDSAContext(tmp_context);
}
void set_peerPublic(const X<Curve, lime::Xtype::publicKey> &peerPublic) override {; /**< Peer Public key */
void set_peerPublic(const X<Curve, lime::Xtype::publicKey> &peerPublic) override {
bctbx_ECDHSetPeerPublicKey(m_context, peerPublic.data(), peerPublic.ssize());
}
void set_peerPublic(const DSA<Curve, lime::DSAtype::publicKey> &peerPublic) override {; /**< Peer Public key */
void set_peerPublic(const DSA<Curve, lime::DSAtype::publicKey> &peerPublic) override {
// we must create a temporary bctbx_EDDSA context and set the given key in
auto tmp_context = bctbx_EDDSAInit<Curve>();
bctbx_EDDSA_setPublicKey(tmp_context, peerPublic.data(), peerPublic.ssize());
......@@ -370,34 +330,19 @@ class bctbx_ECDH : public keyExchange<Curve> {
bctbx_DestroyEDDSAContext(tmp_context);
}
/**
* @brief generate a new random ECDH key pair
*
* @param[in] rng The Random Number Generator to be used to generate the private kay
*/
void createKeyPair(std::shared_ptr<lime::RNG> rng) override {
// the dynamic cast will generate an exception if RNG is not actually a bctbx_RNG
bctbx_ECDHCreateKeyPair(m_context, (int (*)(void *, uint8_t *, size_t))bctbx_rng_get, dynamic_cast<lime::bctbx_RNG&>(*rng).get_context());
}
/**
* @brief Compute the self public key using the secret already set in context
*/
void deriveSelfPublic(void) override {
bctbx_ECDHDerivePublicKey(m_context);
}
/**
* @brief Perform the ECDH computation, shared secret is then available in the object via get_sharedSecret
*/
void computeSharedSecret(void) override {
bctbx_ECDHComputeSecret(m_context, nullptr, nullptr);
}
/**
* ctor/dtor
*/
bctbx_ECDH() {
m_context = bctbx_ECDHInit<Curve>();
}
......@@ -536,6 +481,12 @@ template <> bool AEAD_decrypt<AES256GCM>(const uint8_t *const key, const size_t
static_assert(BCTBX_EDDSA_448_SIGNATURE_SIZE == DSA<C448, DSAtype::signature>::ssize(), "bctoolbox and local defines mismatch");
#endif //EC448_ENABLED
/**
* @brief force a buffer values to zero in a way that shall prevent the compiler from optimizing it out
*
* @param[in,out] buffer the buffer to be cleared
* @param[in] size buffer size
*/
void cleanBuffer(uint8_t *buffer, size_t size) {
bctbx_clean(buffer, size);
}
......
......@@ -31,16 +31,12 @@ namespace lime {
/********************** Data Structures **********************************************************/
/*************************************************************************************************/
/**
* @brief force a buffer values to zero in a way that shall prevent the compiler from optimizing it out
*
* @param[in,out] buffer the buffer to be cleared
* @param[in] size buffer size
*/
void cleanBuffer(uint8_t *buffer, size_t size);
/**
* auto clean fixed size buffer(std::array based)
* @brief auto clean fixed size buffer(std::array based)
*
* Buffers are cleaned when destroyed, use this to store any sensitive data
*/
template <size_t T>
struct sBuffer : public std::array<uint8_t, T> {
......@@ -52,7 +48,9 @@ namespace lime {
/* Key Exchange Data structures */
/****************************************************************/
/**
* Base buffer definition for Key Exchange data structure : easy use of array types with correct size
* @brief Base buffer definition for Key Exchange data structure
*
* easy use of array types with correct size
*/
template <typename Curve, lime::Xtype dataType>
class X : public sBuffer<static_cast<size_t>(Curve::Xsize(dataType))>{
......@@ -67,7 +65,7 @@ namespace lime {
};
/**
* Key pair structure for key exchange algorithm
* @brief Key pair structure for key exchange algorithm
*/
template <typename Curve>
class Xpair {
......@@ -91,7 +89,9 @@ namespace lime {
/* Digital Signature Algorithm data structures */
/****************************************************************/
/**
* Base buffer definition for DSA data structure : easy use of array types with correct size
* @brief Base buffer definition for DSA data structure
*
* easy use of array types with correct size
*/
template <typename Curve, lime::DSAtype dataType>
class DSA : public sBuffer<static_cast<size_t>(Curve::DSAsize(dataType))>{
......@@ -106,7 +106,7 @@ namespace lime {
};
/**
* Key pair structure for DSA algorithm
* @brief Key pair structure for DSA algorithm
*/
template <typename Curve>
class DSApair {
......@@ -131,7 +131,8 @@ namespace lime {
/*************************************************************************************************/
/**
* Random number generator
* @brief Random number generator interface
*
* This abstract class is used to hold a RNG object which then is passed to internal crypto primitives
* who may need it (and dynamically cast to their need which it must fit)
* The only "external" use of RNG is to generate a random seed and some 32 bits id, provide explicit
......@@ -159,26 +160,46 @@ class RNG {
}; //class RNG
/**
* Key exchange wrapper:
* - shall be able to wrap around any algorithm providing key exchange
* - wrapped in algorithms must support key format convertion function from matching Digital Signature algorithm
* @brief Key exchange interface
*
* shall be able to provide an interface to any algorithm implementing key exchange
* @note wrapped in algorithms must support key format convertion function from matching Digital Signature algorithm
*/
template <typename Curve>
class keyExchange {
public:
/* accessors */
virtual const X<Curve, lime::Xtype::privateKey> get_secret(void) = 0; /**< Secret key */
virtual const X<Curve, lime::Xtype::publicKey> get_selfPublic(void) = 0; /**< Self Public key */
virtual const X<Curve, lime::Xtype::publicKey> get_peerPublic(void) = 0; /**< Peer Public key */
virtual const X<Curve, lime::Xtype::sharedSecret> get_sharedSecret(void) = 0; /**< ECDH output */