This repository has been archived by the owner on May 25, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add: reimplementation of toxencryptsave
- Loading branch information
Showing
13 changed files
with
481 additions
and
255 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,8 @@ | ||
add_library(toxencryptsave toxencryptsave.cpp) | ||
add_library(toxencryptsave | ||
constants.cpp | ||
key.cpp | ||
reader.cpp | ||
writer.cpp | ||
toxencryptsave.cpp | ||
) | ||
target_link_libraries(toxencryptsave toxcore ${SODIUM_LIBRARIES}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#include "constants.hpp" | ||
|
||
#include <sodium.h> | ||
|
||
const char* toxencryptsave::constants::magic = TOXENCRYPTSAVE_MAGIC_NUMBER; | ||
|
||
#if TOXENCRYPTSAVE_SALT_LENGTH != crypto_pwhash_scryptsalsa208sha256_SALTBYTES | ||
#error TOXENCRYPTSAVE_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES | ||
#endif | ||
|
||
#if TOXENCRYPTSAVE_KEY_LENGTH != crypto_box_BEFORENMBYTES | ||
#error TOXENCRYPTSAVE_KEY_LENGTH is assumed to be equal to crypto_box_BEFORENMBYTES | ||
#endif | ||
|
||
#if TOXENCRYPTSAVE_NONCEBYTES != crypto_box_NONCEBYTES | ||
#error TOXENCRYPTSAVE_NONCEBYTES is assumed to be equal to crypto_box_NONCEBYTES | ||
#endif | ||
|
||
#if TOXENCRYPTSAVE_ENCRYPTION_EXTRA_LENGTH != (crypto_box_MACBYTES + TOXENCRYPTSAVE_NONCEBYTES + TOXENCRYPTSAVE_SALT_LENGTH + TOXENCRYPTSAVE_MAGIC_LENGTH) | ||
#error TOXENCRYPTSAVE_ENCRYPTION_EXTRA_LENGTH is assumed to be equal to (crypto_box_MACBYTES + TOXENCRYPTSAVE_NONCEBYTES + TOXENCRYPTSAVE_SALT_LENGTH + TOXENCRYPTSAVE_MAGIC_LENGTH) | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#ifndef TOXENCRYPTSAVE_CONSTANTS_H | ||
#define TOXENCRYPTSAVE_CONSTANTS_H | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
// hardcoded constants | ||
// if they change, userdata will be lost | ||
|
||
#define TOXENCRYPTSAVE_MAGIC_NUMBER "toxEsave" | ||
#define TOXENCRYPTSAVE_MAGIC_LENGTH 8U | ||
|
||
#define TOXENCRYPTSAVE_SALT_LENGTH 32U | ||
#define TOXENCRYPTSAVE_KEY_LENGTH 32U | ||
#define TOXENCRYPTSAVE_NONCEBYTES 24U | ||
#define TOXENCRYPTSAVE_ENCRYPTION_EXTRA_LENGTH 80U | ||
|
||
namespace toxencryptsave | ||
{ | ||
namespace constants | ||
{ | ||
extern const char* magic; | ||
static const size_t magic_len = TOXENCRYPTSAVE_MAGIC_LENGTH; | ||
static const size_t salt_len = TOXENCRYPTSAVE_SALT_LENGTH; | ||
static const size_t nonce_len = TOXENCRYPTSAVE_NONCEBYTES; | ||
static const size_t pass_hash_len = TOXENCRYPTSAVE_KEY_LENGTH; | ||
static const size_t encrypted_overhead = TOXENCRYPTSAVE_ENCRYPTION_EXTRA_LENGTH; | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#ifndef TOXENCRYPTSAVE_DATA_DESCRIPTION_H | ||
#define TOXENCRYPTSAVE_DATA_DESCRIPTION_H | ||
|
||
#include "constants.hpp" | ||
|
||
namespace toxencryptsave | ||
{ | ||
|
||
namespace offsets | ||
{ | ||
static const size_t base = 0; | ||
static const size_t magic = base; | ||
static const size_t salt = magic + constants::magic_len; | ||
static const size_t nonce = salt + constants::salt_len; | ||
static const size_t crypted_raw = nonce + constants::nonce_len; | ||
}; | ||
|
||
template<class PointerT> | ||
struct Data_Description /* encryptsave data offsets + length */ | ||
{ | ||
PointerT const base; // 0 offset from the given pointer to data | ||
PointerT const magic; | ||
PointerT const salt; | ||
PointerT const nonce; | ||
PointerT const crypted_raw; | ||
|
||
explicit Data_Description(PointerT const data): | ||
base( data + offsets::base ), | ||
magic( data + offsets::magic ), | ||
salt( data + offsets::salt ), | ||
nonce( data + offsets::nonce ), | ||
crypted_raw( data + offsets::crypted_raw ) | ||
{} | ||
|
||
private: | ||
Data_Description(); // = delete | ||
Data_Description(const Data_Description&); // = delete | ||
Data_Description& operator= (const Data_Description&); // = delete | ||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#ifndef TOXENCRYPTSAVE_ERROR_STATUS_H | ||
#define TOXENCRYPTSAVE_ERROR_STATUS_H | ||
|
||
typedef enum TOX_ERR_KEY_DERIVATION { | ||
TOX_ERR_KEY_DERIVATION_OK, | ||
/** | ||
* Some input data, or maybe the output pointer, was null. | ||
*/ | ||
TOX_ERR_KEY_DERIVATION_NULL, | ||
/** | ||
* The crypto lib was unable to derive a key from the given passphrase, | ||
* which is usually a lack of memory issue. The functions accepting keys | ||
* do not produce this error. | ||
*/ | ||
TOX_ERR_KEY_DERIVATION_FAILED | ||
} TOX_ERR_KEY_DERIVATION; | ||
|
||
typedef enum TOX_ERR_ENCRYPTION { | ||
TOX_ERR_ENCRYPTION_OK, | ||
/** | ||
* Some input data, or maybe the output pointer, was null. | ||
*/ | ||
TOX_ERR_ENCRYPTION_NULL, | ||
/** | ||
* The crypto lib was unable to derive a key from the given passphrase, | ||
* which is usually a lack of memory issue. The functions accepting keys | ||
* do not produce this error. | ||
*/ | ||
TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED, | ||
/** | ||
* The encryption itself failed. | ||
*/ | ||
TOX_ERR_ENCRYPTION_FAILED | ||
} TOX_ERR_ENCRYPTION; | ||
|
||
typedef enum TOX_ERR_DECRYPTION { | ||
TOX_ERR_DECRYPTION_OK, | ||
/** | ||
* Some input data, or maybe the output pointer, was null. | ||
*/ | ||
TOX_ERR_DECRYPTION_NULL, | ||
/** | ||
* The input data was shorter than TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes | ||
*/ | ||
TOX_ERR_DECRYPTION_INVALID_LENGTH, | ||
/** | ||
* The input data is missing the magic number (i.e. wasn't created by this | ||
* module, or is corrupted) | ||
*/ | ||
TOX_ERR_DECRYPTION_BAD_FORMAT, | ||
/** | ||
* The crypto lib was unable to derive a key from the given passphrase, | ||
* which is usually a lack of memory issue. The functions accepting keys | ||
* do not produce this error. | ||
*/ | ||
TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED, | ||
/** | ||
* The encrypted byte array could not be decrypted. Either the data was | ||
* corrupt or the password/key was incorrect. | ||
*/ | ||
TOX_ERR_DECRYPTION_FAILED | ||
} TOX_ERR_DECRYPTION; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "key.hpp" | ||
|
||
#include <sodium.h> | ||
#include <string.h> | ||
|
||
#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} | ||
|
||
bool TOX_PASS_KEY::derive_from_pass_with_salt(uint8_t* passphrase, size_t pplength, const uint8_t* new_salt, TOX_ERR_KEY_DERIVATION* error) | ||
{ | ||
if (!new_salt || (!passphrase && pplength != 0)) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); | ||
return false; | ||
} | ||
|
||
uint8_t passkey[toxencryptsave::constants::pass_hash_len]; | ||
crypto_hash_sha256(passkey, passphrase, pplength); | ||
sodium_memzero(passphrase, pplength); /* wipe plaintext pw */ | ||
memmove(salt, new_salt, toxencryptsave::constants::salt_len); | ||
|
||
/* Derive a key from the password */ | ||
/* http://doc.libsodium.org/key_derivation/README.html */ | ||
/* note that, according to the documentation, a generic pwhash interface will be created | ||
* once the pwhash competition (https://password-hashing.net/) is over */ | ||
if (crypto_pwhash_scryptsalsa208sha256( | ||
key, toxencryptsave::constants::pass_hash_len, | ||
reinterpret_cast<char*>(passkey), sizeof(passkey), | ||
salt, | ||
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */ | ||
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { | ||
/* out of memory most likely */ | ||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); | ||
return false; | ||
} | ||
|
||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK); | ||
return true; | ||
} | ||
|
||
bool TOX_PASS_KEY::derive_from_pass_with_random_salt(uint8_t* passphrase, size_t pplength, TOX_ERR_KEY_DERIVATION* error) | ||
{ | ||
uint8_t salt[toxencryptsave::constants::salt_len]; | ||
randombytes(salt, sizeof salt); | ||
return this->derive_from_pass_with_salt(passphrase, pplength, salt, error); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#ifndef TOXENCRYPTSAVE_KEY_H | ||
#define TOXENCRYPTSAVE_KEY_H | ||
|
||
#include "constants.hpp" | ||
#include "error_status.hpp" | ||
|
||
/* This key structure's internals should not be used by any client program, even | ||
* if they are straightforward here. | ||
*/ | ||
|
||
struct TOX_PASS_KEY | ||
{ | ||
uint8_t salt[TOXENCRYPTSAVE_SALT_LENGTH]; | ||
uint8_t key[TOXENCRYPTSAVE_KEY_LENGTH]; | ||
|
||
bool derive_from_pass_with_salt(uint8_t* passphrase, size_t pplength, const uint8_t* salt, TOX_ERR_KEY_DERIVATION* error); | ||
bool derive_from_pass_with_random_salt(uint8_t* passphrase, size_t pplength, TOX_ERR_KEY_DERIVATION* error); | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#include "reader.hpp" | ||
|
||
#include <sodium.h> | ||
#include <string.h> | ||
|
||
#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}} | ||
|
||
#include <toxcore/crypto_core.hpp> | ||
|
||
namespace toxencryptsave | ||
{ | ||
|
||
bool Reader::magic_is_valid() const { | ||
if (!ro_data.base) | ||
return false; | ||
|
||
return sodium_memcmp(ro_data.magic, constants::magic, constants::magic_len) == 0; | ||
} | ||
|
||
bool Reader::extract_salt_into(uint8_t*const out_salt) const { | ||
if (!this->magic_is_valid() || !out_salt) | ||
return false; | ||
|
||
memcpy(out_salt, ro_data.salt, constants::salt_len); | ||
return true; | ||
} | ||
|
||
bool Reader::extract_key_into(uint8_t* passphrase, size_t pplength, TOX_PASS_KEY* out_key, TOX_ERR_KEY_DERIVATION* error) const | ||
{ | ||
if (!ro_data.base || !out_key || (!passphrase && pplength != 0)) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL); | ||
return false; | ||
} | ||
|
||
if ( !this->extract_salt_into(out_key->salt) ) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED); | ||
return false; | ||
} | ||
|
||
return out_key->derive_from_pass_with_salt(passphrase, pplength, out_key->salt, error); | ||
} | ||
|
||
bool Reader::decrypt_by_key(size_t data_length, const TOX_PASS_KEY* key, uint8_t* out, TOX_ERR_DECRYPTION* error) const | ||
{ | ||
if (data_length <= constants::encrypted_overhead) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH); | ||
return false; | ||
} | ||
|
||
if (!ro_data.base || !key || !out) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL); | ||
return false; | ||
} | ||
|
||
if (!this->magic_is_valid()) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); | ||
return false; | ||
} | ||
|
||
size_t decrypt_expected_length = data_length - constants::encrypted_overhead; | ||
int decrypted_result = decrypt_data_symmetric(key->key, ro_data.nonce, ro_data.crypted_raw, decrypt_expected_length + crypto_box_MACBYTES, out); | ||
|
||
if (decrypted_result == -1) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED); | ||
return false; | ||
} | ||
|
||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_OK); | ||
return true; | ||
} | ||
|
||
bool Reader::decrypt_by_passphrase(size_t data_length, uint8_t* passphrase, size_t pplength, uint8_t* out, TOX_ERR_DECRYPTION* error) const | ||
{ | ||
if (!ro_data.base) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL); | ||
return false; | ||
} | ||
|
||
if ( !this->magic_is_valid() ) { | ||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT); | ||
return false; | ||
} | ||
|
||
/* extract the key */ | ||
TOX_PASS_KEY key; | ||
if ( !this->extract_key_into(passphrase, pplength, &key, NULL)) { | ||
/* out of memory most likely */ | ||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED); | ||
return false; | ||
} | ||
|
||
return this->decrypt_by_key(data_length, &key, out, error); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef TOXENCRYPTSAVE_READER_H | ||
#define TOXENCRYPTSAVE_READER_H | ||
|
||
#include "data_description.hpp" | ||
#include "key.hpp" | ||
|
||
namespace toxencryptsave | ||
{ | ||
|
||
struct Reader | ||
{ | ||
Data_Description<const uint8_t*> const ro_data; | ||
|
||
explicit Reader(const uint8_t* const raw_encryptsave_data): | ||
ro_data( raw_encryptsave_data ) | ||
{} | ||
|
||
bool magic_is_valid() const; | ||
|
||
bool extract_salt_into(uint8_t* const out_salt) const; | ||
bool extract_key_into(uint8_t* const passphrase, size_t pplength, TOX_PASS_KEY* const out_key, TOX_ERR_KEY_DERIVATION* error) const; | ||
|
||
bool decrypt_by_key(size_t data_length, const TOX_PASS_KEY* key, uint8_t* out, TOX_ERR_DECRYPTION* error) const; | ||
bool decrypt_by_passphrase(size_t data_length, uint8_t* passphrase, size_t pplength, uint8_t* out, TOX_ERR_DECRYPTION* error) const; | ||
|
||
private: | ||
Reader(); // = delete | ||
Reader(const Reader&); // = delete | ||
Reader& operator= (const Reader&); // = delete | ||
}; | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.