mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'master' of https://github.com/dubslow/toxcore
This commit is contained in:
commit
99e0fde297
|
@ -55,7 +55,6 @@ END_TEST
|
|||
|
||||
START_TEST(test_save_friend)
|
||||
{
|
||||
TOX_ERR_ENCRYPTED_NEW err = TOX_ERR_ENCRYPTED_NEW_OK;
|
||||
Tox *tox1 = tox_new(0, 0, 0, 0);
|
||||
Tox *tox2 = tox_new(0, 0, 0, 0);
|
||||
ck_assert_msg(tox1 || tox2, "Failed to create 2 tox instances");
|
||||
|
@ -63,99 +62,109 @@ START_TEST(test_save_friend)
|
|||
tox_callback_friend_request(tox2, accept_friend_request, &to_compare);
|
||||
uint8_t address[TOX_ADDRESS_SIZE];
|
||||
tox_self_get_address(tox2, address);
|
||||
int test = tox_friend_add(tox1, address, (uint8_t *)"Gentoo", 7, 0);
|
||||
ck_assert_msg(test == 0, "Failed to add friend error code: %i", test);
|
||||
uint32_t test = tox_friend_add(tox1, address, (uint8_t *)"Gentoo", 7, 0);
|
||||
ck_assert_msg(test != UINT32_MAX, "Failed to add friend");
|
||||
|
||||
uint32_t size = tox_encrypted_size(tox1);
|
||||
size_t size = tox_get_savedata_size(tox1);
|
||||
uint8_t data[size];
|
||||
test = tox_encrypted_save(tox1, data, "correcthorsebatterystaple", 25);
|
||||
ck_assert_msg(test == 0, "failed to encrypted save");
|
||||
//ck_assert_msg(tox_is_save_encrypted(data) == 1, "magic number missing");
|
||||
tox_get_savedata(tox1, data);
|
||||
size_t size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
uint8_t enc_data[size2];
|
||||
TOX_ERR_ENCRYPTION error1;
|
||||
bool ret = tox_pass_encrypt(data, size, "correcthorsebatterystaple", 25, enc_data, &error1);
|
||||
ck_assert_msg(ret, "failed to encrypted save: %u", error1);
|
||||
ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing");
|
||||
|
||||
Tox *tox3 = tox_encrypted_new(0, data, size, "correcthorsebatterystaple", 25, &err);
|
||||
ck_assert_msg(err == TOX_ERR_ENCRYPTED_NEW_OK, "failed to encrypted new");
|
||||
TOX_ERR_NEW err2;
|
||||
Tox *tox3 = tox_new(0, enc_data, size2, &err2);
|
||||
ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %u. should fail with %u", err2,
|
||||
TOX_ERR_NEW_LOAD_ENCRYPTED);
|
||||
uint8_t dec_data[size];
|
||||
TOX_ERR_DECRYPTION err3;
|
||||
ret = tox_pass_decrypt(enc_data, size2, "correcthorsebatterystaple", 25, dec_data, &err3);
|
||||
ck_assert_msg(ret, "failed to decrypt save: %u", err3);
|
||||
tox3 = tox_new(0, dec_data, size, &err2);
|
||||
ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %u", err2);
|
||||
uint8_t address2[TOX_PUBLIC_KEY_SIZE];
|
||||
test = tox_friend_get_public_key(tox3, 0, address2, 0);
|
||||
ck_assert_msg(test == 1, "no friends!");
|
||||
ret = tox_friend_get_public_key(tox3, 0, address2, 0);
|
||||
ck_assert_msg(ret, "no friends!");
|
||||
ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match!");
|
||||
|
||||
size = tox_encrypted_size(tox3);
|
||||
size = tox_get_savedata_size(tox3);
|
||||
uint8_t data2[size];
|
||||
tox_get_savedata(tox3, data2);
|
||||
uint8_t key[32 + crypto_box_BEFORENMBYTES];
|
||||
memcpy(key, salt, 32);
|
||||
memcpy(key + 32, known_key2, crypto_box_BEFORENMBYTES);
|
||||
test = tox_encrypted_key_save(tox3, data2, key);
|
||||
ck_assert_msg(test == 0, "failed to encrypted save the second");
|
||||
//ck_assert_msg(tox_is_save_encrypted(data2) == 1, "magic number the second missing");
|
||||
size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
uint8_t encdata2[size2];
|
||||
ret = tox_pass_key_encrypt(data2, size, key, encdata2, &error1);
|
||||
ck_assert_msg(ret, "failed to key encrypt %u", error1);
|
||||
ck_assert_msg(tox_is_data_encrypted(encdata2), "magic number the second missing");
|
||||
|
||||
// first test tox_encrypted_key_new
|
||||
Tox *tox4 = tox_encrypted_key_new(0, data2, size, key, &err);
|
||||
ck_assert_msg(err == TOX_ERR_ENCRYPTED_NEW_OK, "failed to encrypted new the second");
|
||||
uint8_t address4[TOX_PUBLIC_KEY_SIZE];
|
||||
test = tox_friend_get_public_key(tox4, 0, address4, 0);
|
||||
ck_assert_msg(test == 1, "no friends! the second");
|
||||
ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match! the second");
|
||||
|
||||
// now test compaitibilty with tox_encrypted_new, first manually...
|
||||
uint8_t out1[size], out2[size];
|
||||
//printf("Trying to decrypt from pw:\n");
|
||||
uint32_t sz1 = tox_pass_decrypt(data2, size, pw, pwlen, out1);
|
||||
uint32_t sz2 = tox_pass_key_decrypt(data2, size, key, out2);
|
||||
ck_assert_msg(sz1 == sz2, "differing output sizes");
|
||||
ck_assert_msg(memcmp(out1, out2, sz1) == 0, "differing output data");
|
||||
ret = tox_pass_decrypt(encdata2, size2, pw, pwlen, out1, &err3);
|
||||
ck_assert_msg(ret, "failed to pw decrypt %u", err3);
|
||||
ret = tox_pass_key_decrypt(encdata2, size2, key, out2, &err3);
|
||||
ck_assert_msg(ret, "failed to key decrypt %u", err3);
|
||||
ck_assert_msg(memcmp(out1, out2, size) == 0, "differing output data");
|
||||
|
||||
// and now with the code in use (I only bothered with manually to debug this, and it seems a waste
|
||||
// to remove the manual check now that it's there)
|
||||
Tox *tox5 = tox_encrypted_new(0, data2, size, pw, pwlen, &err);
|
||||
ck_assert_msg(err == TOX_ERR_ENCRYPTED_NEW_OK, "failed to encrypted new the third");
|
||||
Tox *tox4 = tox_new(0, out1, size, &err2);
|
||||
ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third");
|
||||
uint8_t address5[TOX_PUBLIC_KEY_SIZE];
|
||||
test = tox_friend_get_public_key(tox4, 0, address5, 0);
|
||||
ck_assert_msg(test == 1, "no friends! the third");
|
||||
ret = tox_friend_get_public_key(tox4, 0, address5, 0);
|
||||
ck_assert_msg(ret, "no friends! the third");
|
||||
ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match! the third");
|
||||
|
||||
tox_kill(tox1);
|
||||
tox_kill(tox2);
|
||||
tox_kill(tox3);
|
||||
tox_kill(tox4);
|
||||
tox_kill(tox5);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_keys)
|
||||
{
|
||||
uint8_t key[tox_pass_key_length()];
|
||||
tox_derive_key_from_pass("123qweasdzxc", 12, key);
|
||||
TOX_ERR_ENCRYPTION encerr;
|
||||
TOX_ERR_DECRYPTION decerr;
|
||||
TOX_ERR_KEY_DERIVATION keyerr;
|
||||
uint8_t key[TOX_PASS_KEY_LENGTH];
|
||||
bool ret = tox_derive_key_from_pass("123qweasdzxc", 12, key, &keyerr);
|
||||
ck_assert_msg(ret, "generic failure 1: %u", keyerr);
|
||||
uint8_t *string = "No Patrick, mayonnaise is not an instrument."; // 44
|
||||
|
||||
uint8_t encrypted[44 + tox_pass_encryption_extra_length()];
|
||||
int sz = tox_pass_key_encrypt(string, 44, key, encrypted);
|
||||
uint8_t encrypted[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
|
||||
ret = tox_pass_key_encrypt(string, 44, key, encrypted, &encerr);
|
||||
ck_assert_msg(ret, "generic failure 2: %u", encerr);
|
||||
|
||||
uint8_t encrypted2[44 + tox_pass_encryption_extra_length()];
|
||||
int sz2 = tox_pass_encrypt(string, 44, "123qweasdzxc", 12, encrypted2);
|
||||
uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
|
||||
ret = tox_pass_encrypt(string, 44, "123qweasdzxc", 12, encrypted2, &encerr);
|
||||
ck_assert_msg(ret, "generic failure 3: %u", encerr);
|
||||
|
||||
ck_assert_msg(sz == sz2, "an encryption failed");
|
||||
uint8_t out1[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
|
||||
uint8_t out2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
|
||||
|
||||
uint8_t out1[44 + tox_pass_encryption_extra_length()];
|
||||
uint8_t out2[44 + tox_pass_encryption_extra_length()];
|
||||
|
||||
sz = tox_pass_key_decrypt(encrypted, 44 + tox_pass_encryption_extra_length(), key, out1);
|
||||
ck_assert_msg(sz == 44, "sz isn't right");
|
||||
ret = tox_pass_key_decrypt(encrypted, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, key, out1, &decerr);
|
||||
ck_assert_msg(ret, "generic failure 4: %u", decerr);
|
||||
ck_assert_msg(memcmp(out1, string, 44) == 0, "decryption 1 failed");
|
||||
|
||||
sz2 = tox_pass_decrypt(encrypted2, 44 + tox_pass_encryption_extra_length(), "123qweasdzxc", 12, out2);
|
||||
ck_assert_msg(sz2 == 44, "sz2 isn't right");
|
||||
ret = tox_pass_decrypt(encrypted2, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, "123qweasdzxc", 12, out2, &decerr);
|
||||
ck_assert_msg(ret, "generic failure 5: %u", &decerr);
|
||||
ck_assert_msg(memcmp(out2, string, 44) == 0, "decryption 2 failed");
|
||||
|
||||
// test that pass_decrypt can decrypt things from pass_key_encrypt
|
||||
sz = tox_pass_decrypt(encrypted, 44 + tox_pass_encryption_extra_length(), "123qweasdzxc", 12, out1);
|
||||
ck_assert_msg(sz == 44, "sz isn't right");
|
||||
ret = tox_pass_decrypt(encrypted, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, "123qweasdzxc", 12, out1, &decerr);
|
||||
ck_assert_msg(ret, "generic failure 6: %u", decerr);
|
||||
ck_assert_msg(memcmp(out1, string, 44) == 0, "decryption 3 failed");
|
||||
|
||||
uint8_t salt[tox_pass_salt_length()];
|
||||
ck_assert_msg(0 == tox_get_salt(encrypted, salt), "couldn't get salt");
|
||||
uint8_t key2[tox_pass_key_length()];
|
||||
tox_derive_key_with_salt("123qweasdzxc", 12, salt, key2);
|
||||
ck_assert_msg(0 == memcmp(key, key2, tox_pass_key_length()), "salt comparison failed");
|
||||
uint8_t salt[TOX_PASS_SALT_LENGTH];
|
||||
ck_assert_msg(tox_get_salt(encrypted, salt), "couldn't get salt");
|
||||
uint8_t key2[TOX_PASS_KEY_LENGTH];
|
||||
ret = tox_derive_key_with_salt("123qweasdzxc", 12, salt, key2, &keyerr);
|
||||
ck_assert_msg(ret, "generic failure 7: %u", keyerr);
|
||||
ck_assert_msg(0 == memcmp(key, key2, TOX_PASS_KEY_LENGTH), "salt comparison failed");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
@ -163,7 +172,7 @@ Suite *encryptsave_suite(void)
|
|||
{
|
||||
Suite *s = suite_create("encryptsave");
|
||||
|
||||
DEFTESTCASE_SLOW(known_kdf, 60); /* is 5-10 seconds on my computer, but is directly dependent on CPU */
|
||||
DEFTESTCASE_SLOW(known_kdf, 60);
|
||||
DEFTESTCASE_SLOW(save_friend, 20);
|
||||
DEFTESTCASE_SLOW(keys, 30);
|
||||
|
||||
|
|
|
@ -37,81 +37,69 @@
|
|||
#include <crypto_hash_sha256.h>
|
||||
#endif
|
||||
|
||||
#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH (crypto_box_MACBYTES + crypto_box_NONCEBYTES \
|
||||
+ crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
|
||||
#if TOX_PASS_SALT_LENGTH != crypto_pwhash_scryptsalsa208sha256_SALTBYTES
|
||||
#error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES
|
||||
#endif
|
||||
|
||||
#define TOX_PASS_KEY_LENGTH (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES)
|
||||
#if TOX_PASS_KEY_LENGTH != (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES)
|
||||
#error TOX_PASS_KEY_LENGTH is assumed to be equal to (crypto_pwhash_scryptsalsa208sha256_SALTBYTES + crypto_box_KEYBYTES)
|
||||
#endif
|
||||
|
||||
int tox_pass_encryption_extra_length()
|
||||
{
|
||||
return TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
}
|
||||
#if TOX_PASS_ENCRYPTION_EXTRA_LENGTH != (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
|
||||
#error TOX_PASS_ENCRYPTION_EXTRA_LENGTH is assumed to be equal to (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
|
||||
#endif
|
||||
|
||||
int tox_pass_key_length()
|
||||
{
|
||||
return TOX_PASS_KEY_LENGTH;
|
||||
}
|
||||
|
||||
int tox_pass_salt_length()
|
||||
{
|
||||
return crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
|
||||
}
|
||||
|
||||
/* This "module" provides functions analogous to tox_load and tox_save in toxcore
|
||||
* Clients should consider alerting their users that, unlike plain data, if even one bit
|
||||
/* Clients should consider alerting their users that, unlike plain data, if even one bit
|
||||
* becomes corrupted, the data will be entirely unrecoverable.
|
||||
* Ditto if they forget their password, there is no way to recover the data.
|
||||
*/
|
||||
|
||||
/* return size of the messenger data (for encrypted saving). */
|
||||
uint32_t tox_encrypted_size(const Tox *tox)
|
||||
{
|
||||
return tox_get_savedata_size(tox) + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
}
|
||||
|
||||
/* This retrieves the salt used to encrypt the given data, which can then be passed to
|
||||
* derive_key_with_salt to produce the same key as was previously used. Any encrpyted
|
||||
* data with this module can be used as input.
|
||||
*
|
||||
* returns -1 if the magic number is wrong
|
||||
* returns 0 otherwise (no guarantee about validity of data)
|
||||
* returns true if magic number matches
|
||||
* success does not say anything about the validity of the data, only that data of
|
||||
* the appropriate size was copied
|
||||
*/
|
||||
int tox_get_salt(uint8_t *data, uint8_t *salt)
|
||||
bool tox_get_salt(const uint8_t *data, uint8_t *salt)
|
||||
{
|
||||
if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
data += TOX_ENC_SAVE_MAGIC_LENGTH;
|
||||
memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Generates a secret symmetric key from the given passphrase. out_key must be at least
|
||||
* TOX_PASS_KEY_LENGTH bytes long.
|
||||
* Be sure to not compromise the key! Only keep it in memory, do not write to disk.
|
||||
* This function is fairly cheap, but irungentoo insists that you be allowed to
|
||||
* cache the result if you want, to minimize computation for repeated encryptions.
|
||||
* The password is zeroed after key derivation.
|
||||
* The key should only be used with the other functions in this module, as it
|
||||
* includes a salt.
|
||||
* Note that this function is not deterministic; to derive the same key from a
|
||||
* password, you also must know the random salt that was used. See below.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key)
|
||||
bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error)
|
||||
{
|
||||
uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
randombytes(salt, sizeof salt);
|
||||
return tox_derive_key_with_salt(passphrase, pplength, salt, out_key);
|
||||
return tox_derive_key_with_salt(passphrase, pplength, salt, out_key, error);
|
||||
}
|
||||
|
||||
/* Same as above, except with use the given salt for deterministic key derivation.
|
||||
* The salt must be tox_salt_length() bytes in length.
|
||||
*/
|
||||
int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key)
|
||||
bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key,
|
||||
TOX_ERR_KEY_DERIVATION *error)
|
||||
{
|
||||
if (pplength == 0)
|
||||
return -1;
|
||||
if (pplength == 0 || !passphrase || !salt || !out_key) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t passkey[crypto_hash_sha256_BYTES];
|
||||
crypto_hash_sha256(passkey, passphrase, pplength);
|
||||
|
@ -127,27 +115,33 @@ int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *sa
|
|||
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
|
||||
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
|
||||
/* out of memory most likely */
|
||||
return -1;
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
|
||||
memcpy(out_key, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
memcpy(out_key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, key, crypto_box_KEYBYTES);
|
||||
return 0;
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Encrypt arbitrary with a key produced by tox_derive_key_from_pass. The output
|
||||
/* Encrypt arbitrary with a key produced by tox_derive_key_*. The output
|
||||
* array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
|
||||
* key must be TOX_PASS_KEY_LENGTH bytes.
|
||||
* If you already have a symmetric key from somewhere besides this module, simply
|
||||
* call encrypt_data_symmetric in toxcore/crypto_core directly.
|
||||
*
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *key, uint8_t *out)
|
||||
bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out,
|
||||
TOX_ERR_ENCRYPTION *error)
|
||||
{
|
||||
if (data_len == 0 || !data || !key || !out) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the output data consists of, in order:
|
||||
* salt, nonce, mac, enc_data
|
||||
* where the mac is automatically prepended by the encrypt()
|
||||
|
@ -173,78 +167,62 @@ int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *
|
|||
/* now encrypt */
|
||||
if (encrypt_data_symmetric(key, nonce, data, data_len, out)
|
||||
!= data_len + crypto_box_MACBYTES) {
|
||||
return -1;
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_OK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Encrypts the given data with the given passphrase. The output array must be
|
||||
* at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates
|
||||
* to tox_derive_key_from_pass and tox_pass_key_encrypt.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_pass_encrypt(const uint8_t *data, uint32_t data_len, uint8_t *passphrase, uint32_t pplength, uint8_t *out)
|
||||
bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out,
|
||||
TOX_ERR_ENCRYPTION *error)
|
||||
{
|
||||
uint8_t key[TOX_PASS_KEY_LENGTH];
|
||||
TOX_ERR_KEY_DERIVATION _error;
|
||||
|
||||
if (tox_derive_key_from_pass(passphrase, pplength, key) == -1)
|
||||
return -1;
|
||||
if (!tox_derive_key_from_pass(passphrase, pplength, key, &_error)) {
|
||||
if (_error == TOX_ERR_KEY_DERIVATION_NULL) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_NULL);
|
||||
} else if (_error == TOX_ERR_KEY_DERIVATION_FAILED) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED);
|
||||
}
|
||||
|
||||
return tox_pass_key_encrypt(data, data_len, key, out);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save the messenger data encrypted with the given password.
|
||||
* data must be at least tox_encrypted_size().
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
*/
|
||||
int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength)
|
||||
{
|
||||
/* first get plain save data */
|
||||
uint32_t temp_size = tox_get_savedata_size(tox);
|
||||
uint8_t temp_data[temp_size];
|
||||
tox_get_savedata(tox, temp_data);
|
||||
|
||||
/* now encrypt */
|
||||
return tox_pass_encrypt(temp_data, temp_size, passphrase, pplength, data);
|
||||
}
|
||||
|
||||
/* Save the messenger data encrypted with the given key from tox_derive_key.
|
||||
* data must be at least tox_encrypted_size().
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
*/
|
||||
int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key)
|
||||
{
|
||||
/* first get plain save data */
|
||||
uint32_t temp_size = tox_get_savedata_size(tox);
|
||||
uint8_t temp_data[temp_size];
|
||||
tox_get_savedata(tox, temp_data);
|
||||
|
||||
/* encrypt */
|
||||
return tox_pass_key_encrypt(temp_data, temp_size, key, data);
|
||||
return tox_pass_key_encrypt(data, data_len, key, out, error);
|
||||
}
|
||||
|
||||
/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
|
||||
* tox_derive_key_from_pass.
|
||||
*
|
||||
* returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success
|
||||
* returns -1 on failure
|
||||
* the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH
|
||||
*
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out)
|
||||
bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out,
|
||||
TOX_ERR_DECRYPTION *error)
|
||||
{
|
||||
if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH
|
||||
|| 0 != memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH))
|
||||
return -1;
|
||||
if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
data += TOX_ENC_SAVE_MAGIC_LENGTH;
|
||||
|
||||
uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
//uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
|
||||
|
@ -257,20 +235,30 @@ int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *ke
|
|||
/* decrypt the data */
|
||||
if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out)
|
||||
!= decrypt_length) {
|
||||
return -1;
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return decrypt_length;
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_OK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Decrypts the given data with the given passphrase. The output array must be
|
||||
* at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
|
||||
* at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates
|
||||
* to tox_pass_key_decrypt.
|
||||
*
|
||||
* returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success
|
||||
* returns -1 on failure
|
||||
* the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH
|
||||
*
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out)
|
||||
bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out,
|
||||
TOX_ERR_DECRYPTION *error)
|
||||
{
|
||||
if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_BAD_FORMAT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t passkey[crypto_hash_sha256_BYTES];
|
||||
crypto_hash_sha256(passkey, passphrase, pplength);
|
||||
|
||||
|
@ -286,60 +274,18 @@ int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase,
|
|||
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
|
||||
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
|
||||
/* out of memory most likely */
|
||||
return -1;
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
|
||||
|
||||
return tox_pass_key_decrypt(data, length, key, out);
|
||||
}
|
||||
|
||||
/* Load the new messenger from encrypted data of size length.
|
||||
* All other arguments are like toxcore/tox_new().
|
||||
*
|
||||
* returns NULL on failure; see the documentation in toxcore/tox.h.
|
||||
*/
|
||||
Tox *tox_encrypted_new(const struct Tox_Options *options, const uint8_t *data, size_t length, uint8_t *passphrase,
|
||||
size_t pplength, TOX_ERR_ENCRYPTED_NEW *error)
|
||||
{
|
||||
uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
uint8_t temp_data[decrypt_length];
|
||||
|
||||
if (tox_pass_decrypt(data, length, passphrase, pplength, temp_data)
|
||||
!= decrypt_length) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTED_NEW_LOAD_DECRYPTION_FAILED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tox_new(options, temp_data, decrypt_length, error);
|
||||
}
|
||||
|
||||
/* Load the messenger from encrypted data of size length, with key from tox_derive_key.
|
||||
* All other arguments are like toxcore/tox_new().
|
||||
*
|
||||
* returns NULL on failure; see the documentation in toxcore/tox.h.
|
||||
*/
|
||||
Tox *tox_encrypted_key_new(const struct Tox_Options *options, const uint8_t *data, size_t length, uint8_t *key,
|
||||
TOX_ERR_ENCRYPTED_NEW *error)
|
||||
{
|
||||
uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
uint8_t temp_data[decrypt_length];
|
||||
|
||||
if (tox_pass_key_decrypt(data, length, key, temp_data)
|
||||
!= decrypt_length) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTED_NEW_LOAD_DECRYPTION_FAILED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tox_new(options, temp_data, decrypt_length, error);
|
||||
return tox_pass_key_decrypt(data, length, key, out, error);
|
||||
}
|
||||
|
||||
/* Determines whether or not the given data is encrypted (by checking the magic number)
|
||||
*
|
||||
* returns 1 if it is encrypted
|
||||
* returns 0 otherwise
|
||||
*/
|
||||
int tox_is_data_encrypted(const uint8_t *data)
|
||||
bool tox_is_data_encrypted(const uint8_t *data)
|
||||
{
|
||||
if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0)
|
||||
return 1;
|
||||
|
|
|
@ -30,6 +30,7 @@ extern "C" {
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef TOX_DEFINED
|
||||
#define TOX_DEFINED
|
||||
|
@ -37,21 +38,11 @@ typedef struct Tox Tox;
|
|||
struct Tox_Options;
|
||||
#endif
|
||||
|
||||
// these functions provide access to these defines in toxencryptsave.c, which
|
||||
// otherwise aren't actually available in clients...
|
||||
int tox_pass_encryption_extra_length();
|
||||
#define TOX_PASS_SALT_LENGTH 32
|
||||
#define TOX_PASS_KEY_LENGTH 64
|
||||
#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80
|
||||
|
||||
int tox_pass_key_length();
|
||||
|
||||
int tox_pass_salt_length();
|
||||
|
||||
/* return size of the messenger data (for encrypted Messenger saving). */
|
||||
uint32_t tox_encrypted_size(const Tox *tox);
|
||||
|
||||
/* This "module" provides functions analogous to tox_load and tox_save in toxcore,
|
||||
* as well as functions for encryption of arbitrary client data (e.g. chat logs).
|
||||
*
|
||||
* It is conceptually organized into two parts. The first part are the functions
|
||||
/* This module is conceptually organized into two parts. The first part are the functions
|
||||
* with "key" in the name. To use these functions, first derive an encryption key
|
||||
* from a password with tox_derive_key_from_pass, and use the returned key to
|
||||
* encrypt the data. The second part takes the password itself instead of the key,
|
||||
|
@ -61,13 +52,74 @@ uint32_t tox_encrypted_size(const Tox *tox);
|
|||
* favor using the first part intead of the second part.
|
||||
*
|
||||
* The encrypted data is prepended with a magic number, to aid validity checking
|
||||
* (no guarantees are made of course).
|
||||
* (no guarantees are made of course). Any data to be decrypted must start with
|
||||
* the magic number.
|
||||
*
|
||||
* Clients should consider alerting their users that, unlike plain data, if even one bit
|
||||
* becomes corrupted, the data will be entirely unrecoverable.
|
||||
* Ditto if they forget their password, there is no way to recover the data.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/******************************* BEGIN PART 2 *******************************
|
||||
* For simplicty, the second part of the module is presented first. The API for
|
||||
|
@ -77,98 +129,25 @@ uint32_t tox_encrypted_size(const Tox *tox);
|
|||
*/
|
||||
|
||||
/* Encrypts the given data with the given passphrase. The output array must be
|
||||
* at least data_len + tox_pass_encryption_extra_length() bytes long. This delegates
|
||||
* at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates
|
||||
* to tox_derive_key_from_pass and tox_pass_key_encrypt.
|
||||
*
|
||||
* tox_encrypted_save() is a good example of how to use this function.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_pass_encrypt(const uint8_t *data, uint32_t data_len, uint8_t *passphrase, uint32_t pplength, uint8_t *out);
|
||||
bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase, size_t pplength, uint8_t *out,
|
||||
TOX_ERR_ENCRYPTION *error);
|
||||
|
||||
/* Save the messenger data encrypted with the given password.
|
||||
* data must be at least tox_encrypted_size().
|
||||
*
|
||||
* NOTE: Unlike tox_save(), this function may fail. Be sure to check its return
|
||||
* value.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
*/
|
||||
int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength);
|
||||
|
||||
/* Decrypts the given data with the given passphrase. The output array must be
|
||||
* at least data_len - tox_pass_encryption_extra_length() bytes long. This delegates
|
||||
* at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long. This delegates
|
||||
* to tox_pass_key_decrypt.
|
||||
*
|
||||
* tox_encrypted_load() is a good example of how to use this function.
|
||||
* the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH
|
||||
*
|
||||
* returns the length of the output data (== data_len - tox_pass_encryption_extra_length()) on success
|
||||
* returns -1 on failure
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_pass_decrypt(const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength, uint8_t *out);
|
||||
|
||||
typedef enum TOX_ERR_ENCRYPTED_NEW {
|
||||
TOX_ERR_ENCRYPTED_NEW_OK,
|
||||
TOX_ERR_ENCRYPTED_NEW_NULL,
|
||||
/**
|
||||
* The function was unable to allocate enough memory to store the internal
|
||||
* structures for the Tox object.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_MALLOC,
|
||||
/**
|
||||
* The function was unable to bind to a port. This may mean that all ports
|
||||
* have already been bound, e.g. by other Tox instances, or it may mean
|
||||
* a permission error. You may be able to gather more information from errno.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_PORT_ALLOC,
|
||||
/**
|
||||
* proxy_type was invalid.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_PROXY_BAD_TYPE,
|
||||
/**
|
||||
* proxy_type was valid but the proxy_host passed had an invalid format
|
||||
* or was NULL.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_PROXY_BAD_HOST,
|
||||
/**
|
||||
* proxy_type was valid, but the proxy_port was invalid.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_PROXY_BAD_PORT,
|
||||
/**
|
||||
* The proxy host passed could not be resolved.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_PROXY_NOT_FOUND,
|
||||
/**
|
||||
* The byte array to be loaded contained an encrypted save.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_LOAD_ENCRYPTED,
|
||||
/**
|
||||
* The data format was invalid. This can happen when loading data that was
|
||||
* saved by an older version of Tox, or when the data has been corrupted.
|
||||
* When loading from badly formatted data, some data may have been loaded,
|
||||
* and the rest is discarded. Passing an invalid length parameter also
|
||||
* causes this error.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_LOAD_BAD_FORMAT,
|
||||
/**
|
||||
* The encrypted byte array could not be decrypted. Either the data was
|
||||
* corrupt or the password/key was incorrect.
|
||||
*
|
||||
* NOTE: This error code is only set by tox_encrypted_new() and
|
||||
* tox_encrypted_key_new(), in the toxencryptsave module.
|
||||
*/
|
||||
TOX_ERR_ENCRYPTED_NEW_LOAD_DECRYPTION_FAILED
|
||||
} TOX_ERR_ENCRYPTED_NEW;
|
||||
|
||||
/* Load the new messenger from encrypted data of size length.
|
||||
* All other arguments are like toxcore/tox_new().
|
||||
*
|
||||
* returns NULL on failure; see the documentation in toxcore/tox.h.
|
||||
*/
|
||||
Tox *tox_encrypted_new(const struct Tox_Options *options, const uint8_t *data, size_t length, uint8_t *passphrase,
|
||||
size_t pplength, TOX_ERR_ENCRYPTED_NEW *error);
|
||||
bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, size_t pplength, uint8_t *out,
|
||||
TOX_ERR_DECRYPTION *error);
|
||||
|
||||
|
||||
/******************************* BEGIN PART 1 *******************************
|
||||
|
@ -177,7 +156,7 @@ Tox *tox_encrypted_new(const struct Tox_Options *options, const uint8_t *data, s
|
|||
*/
|
||||
|
||||
/* Generates a secret symmetric key from the given passphrase. out_key must be at least
|
||||
* tox_pass_key_length() bytes long.
|
||||
* TOX_PASS_KEY_LENGTH bytes long.
|
||||
* Be sure to not compromise the key! Only keep it in memory, do not write to disk.
|
||||
* The password is zeroed after key derivation.
|
||||
* The key should only be used with the other functions in this module, as it
|
||||
|
@ -185,72 +164,52 @@ Tox *tox_encrypted_new(const struct Tox_Options *options, const uint8_t *data, s
|
|||
* Note that this function is not deterministic; to derive the same key from a
|
||||
* password, you also must know the random salt that was used. See below.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_derive_key_from_pass(uint8_t *passphrase, uint32_t pplength, uint8_t *out_key);
|
||||
bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error);
|
||||
|
||||
/* Same as above, except with use the given salt for deterministic key derivation.
|
||||
* The salt must be tox_salt_length() bytes in length.
|
||||
*/
|
||||
int tox_derive_key_with_salt(uint8_t *passphrase, uint32_t pplength, uint8_t *salt, uint8_t *out_key);
|
||||
bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key,
|
||||
TOX_ERR_KEY_DERIVATION *error);
|
||||
|
||||
/* This retrieves the salt used to encrypt the given data, which can then be passed to
|
||||
* derive_key_with_salt to produce the same key as was previously used. Any encrpyted
|
||||
* data with this module can be used as input.
|
||||
*
|
||||
* returns -1 if the magic number is wrong
|
||||
* returns 0 otherwise (no guarantee about validity of data)
|
||||
* returns true if magic number matches
|
||||
* success does not say anything about the validity of the data, only that data of
|
||||
* the appropriate size was copied
|
||||
*/
|
||||
int tox_get_salt(uint8_t *data, uint8_t *salt);
|
||||
bool tox_get_salt(const uint8_t *data, uint8_t *salt);
|
||||
|
||||
/* Now come the functions that are analogous to the part 2 functions. */
|
||||
|
||||
/* Encrypt arbitrary with a key produced by tox_derive_key_. The output
|
||||
* array must be at least data_len + tox_pass_encryption_extra_length() bytes long.
|
||||
* key must be tox_pass_key_length() bytes.
|
||||
/* Encrypt arbitrary with a key produced by tox_derive_key_*. The output
|
||||
* array must be at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
|
||||
* key must be TOX_PASS_KEY_LENGTH bytes.
|
||||
* If you already have a symmetric key from somewhere besides this module, simply
|
||||
* call encrypt_data_symmetric in toxcore/crypto_core directly.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
* returns true on success
|
||||
*/
|
||||
int tox_pass_key_encrypt(const uint8_t *data, uint32_t data_len, const uint8_t *key, uint8_t *out);
|
||||
|
||||
/* Save the messenger data encrypted with the given key from tox_derive_key.
|
||||
* data must be at least tox_encrypted_size().
|
||||
*
|
||||
* NOTE: Unlike tox_save(), this function may fail. Be sure to check its return
|
||||
* value.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure
|
||||
*/
|
||||
int tox_encrypted_key_save(const Tox *tox, uint8_t *data, uint8_t *key);
|
||||
bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out,
|
||||
TOX_ERR_ENCRYPTION *error);
|
||||
|
||||
/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
|
||||
* tox_derive_key_from_pass.
|
||||
*
|
||||
* returns the length of the output data (== data_len - tox_pass_encryption_extra_length()) on success
|
||||
* returns -1 on failure
|
||||
*/
|
||||
int tox_pass_key_decrypt(const uint8_t *data, uint32_t length, const uint8_t *key, uint8_t *out);
|
||||
|
||||
/* Load the messenger from encrypted data of size length, with key from tox_derive_key.
|
||||
* All other arguments are like toxcore/tox_new().
|
||||
* the output data has size data_length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH
|
||||
*
|
||||
* returns NULL on failure; see the documentation in toxcore/tox.h.
|
||||
* returns true on success
|
||||
*/
|
||||
Tox *tox_encrypted_key_new(const struct Tox_Options *options, const uint8_t *data, size_t length, uint8_t *key,
|
||||
TOX_ERR_ENCRYPTED_NEW *error);
|
||||
|
||||
bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out,
|
||||
TOX_ERR_DECRYPTION *error);
|
||||
|
||||
/* Determines whether or not the given data is encrypted (by checking the magic number)
|
||||
*
|
||||
* returns 1 if it is encrypted
|
||||
* returns 0 otherwise
|
||||
*/
|
||||
int tox_is_data_encrypted(const uint8_t *data);
|
||||
bool tox_is_data_encrypted(const uint8_t *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user