Commit f68d9484 authored by Johan Pascal's avatar Johan Pascal

Add AEAD in crypto cpp API

+ sBuffer : array being wiped out by destructor
parent 9dcc6a6e
......@@ -376,11 +376,6 @@ std::shared_ptr<Signature<Base>> make_Signature() {
}
/* HMAC templates */
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);
template <typename hashAlgo>
void HMAC(const std::vector<uint8_t> &key, const std::vector<uint8_t> &input, std::array<uint8_t, hashAlgo::ssize()> &hash);
/* HMAC must use a specialized template */
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) {
......@@ -437,6 +432,51 @@ template void HMAC_KDF<SHA512, std::string>(const uint8_t *const salt, const siz
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);
/* AEAD template must be specialized */
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) {
/* if this template is instanciated the static_assert will fail but will give us an error message with faulty type */
static_assert(sizeof(AEADAlgo) != sizeof(AEADAlgo), "You must specialize AEAD_encrypt function template");
}
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) {
/* if this template is instanciated the static_assert will fail but will give us an error message with faulty type */
static_assert(sizeof(AEADAlgo) != sizeof(AEADAlgo), "You must specialize AEAD_decrypt function template");
return false;
}
/* AEAD scheme specialiazed template with AES256-GCM, 16 bytes auth tag */
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) {
/* perforn checks on sizes */
if (keySize != AES256GCM::keySize() || tagSize != AES256GCM::tagSize()) {
throw BCTBX_EXCEPTION << "invalid arguments for AEAD_encrypt AES256-GCM";
}
auto ret = bctbx_aes_gcm_encrypt_and_tag(key, keySize, plain, plainSize, AD, ADSize, IV, IVSize, tag, tagSize, cipher);
if (ret != 0) {
throw BCTBX_EXCEPTION << "AEAD_encrypt AES256-GCM error: "<<ret;
}
}
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) {
/* perforn checks on sizes */
if (keySize != AES256GCM::keySize() || tagSize != AES256GCM::tagSize()) {
throw BCTBX_EXCEPTION << "invalid arguments for AEAD_decrypt AES256-GCM";
}
auto ret = bctbx_aes_gcm_decrypt_and_auth(key, keySize, cipher, cipherSize, AD, ADSize, IV, IVSize, tag, tagSize, plain);
if (ret == 0) return true;
if (ret == BCTBX_ERROR_AUTHENTICATION_FAILED) return false;
throw BCTBX_EXCEPTION << "AEAD_decrypt AES256-GCM error: "<<ret;
}
/* check buffer length are in sync with bctoolbox ones */
#ifdef EC25519_ENABLED
static_assert(BCTBX_ECDH_X25519_PUBLIC_SIZE == X<C255, Xtype::publicKey>::ssize(), "bctoolbox and local defines mismatch");
......
......@@ -37,6 +37,14 @@ namespace lime {
* @param[in] size buffer size
*/
void cleanBuffer(uint8_t *buffer, size_t size);
/****************************************************************/
/* auto clean fixed size buffer */
/****************************************************************/
template <size_t T>
struct sBuffer : public std::array<uint8_t, T> {
~sBuffer() {cleanBuffer(this->data(), T);}; // zeroise all buffer when done
};
/****************************************************************/
/* Key Exchange Data structures */
......@@ -246,6 +254,60 @@ 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 *************************************/
/**
* @Brief Encrypt and tag using scheme given as template parameter
*
* @param[in] key Encryption key
* @param[in] keySize Key buffer length, it must match the selected AEAD scheme or an exception is generated
* @param[in] IV Buffer holding the initialisation vector
* @param[in] IVSize Initialisation vector length in bytes
* @param[in] plain buffer to be encrypted
* @param[in] plainSize Length in bytes of buffer to be encrypted
* @param[in] AD Buffer holding additional data to be used in tag computation
* @param[in] ADSize Additional data length in bytes
* @param[out] tag Buffer holding the generated tag
* @param[in] tagSize Requested length for the generated tag, it must match the selected AEAD scheme or an exception is generated
* @param[out] cipher Buffer holding the output, shall be at least the length of plainText buffer
*/
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);
/**
* @Brief Authenticate and Decrypt using scheme given as template parameter
*
* @param[in] key Encryption key
* @param[in] keySize Key buffer length, it must match the selected AEAD scheme or an exception is generated
* @param[in] IV Buffer holding the initialisation vector
* @param[in] IVSize Initialisation vector length in bytes
* @param[in] cipher Buffer holding the data to be decipherd
* @param[in] plainSize Length in bytes of buffer to be encrypted
* @param[in] AD Buffer holding additional data to be used in tag computation
* @param[in] ADSize Additional data length in bytes
* @param[in] tag Buffer holding the authentication tag
* @param[in] tagSize Length for the generated tag, it must match the selected AEAD scheme or an exception is generated
* @param[out] plain buffer holding the plain output, shall be at least the length of plainText buffer
*
* @return true if authentication tag match and decryption was successful
*/
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 ********************************************************/
/*************************************************************************************************/
......@@ -267,6 +329,14 @@ extern template void HMAC_KDF<SHA512, std::string>(const std::vector<uint8_t> &s
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);
extern 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);
extern 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);
#ifdef EC25519_ENABLED
extern template std::shared_ptr<keyExchange<C255>> make_keyExchange();
extern template std::shared_ptr<Signature<C255>> make_Signature();
......
This diff is collapsed.
......@@ -38,15 +38,10 @@ namespace lime {
enum class DRSessionDbStatus : uint8_t {clean, dirty_encrypt, dirty_decrypt, dirty_ratchet, dirty};
// Double Rachet chain keys: Root key, Sender and receiver keys are 32 bytes arrays
class DRChainKey : public std::array<uint8_t, lime::settings::DRChainKeySize> {
public:
~DRChainKey() {cleanBuffer(this->data(), lime::settings::DRChainKeySize);}
};
using DRChainKey = lime::sBuffer<lime::settings::DRChainKeySize>;
// Double Ratchet Message keys : 32 bytes of encryption key followed by 16 bytes of IV
class DRMKey : public std::array<uint8_t, lime::settings::DRMessageKeySize+lime::settings::DRMessageIVSize> {
public:
~DRMKey() {cleanBuffer(this->data(), lime::settings::DRMessageKeySize+lime::settings::DRMessageIVSize);}
};
using DRMKey = lime::sBuffer<lime::settings::DRMessageKeySize+lime::settings::DRMessageIVSize>;
// 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
using SharedADBuffer = std::array<uint8_t, lime::settings::DRSessionSharedADSize>;
......
......@@ -52,6 +52,12 @@ namespace lime {
struct SHA512 {
static constexpr size_t ssize() {return 64;} // maximum output size
};
// AEAD function defines
struct AES256GCM {
static constexpr size_t keySize(void) {return 32;}; // key size is 256 bits
static constexpr size_t tagSize(void) {return 16;}; // authentication tag size is 128 bits
};
}
#endif /* lime_keys_hpp */
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment