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
abff31d2ad
|
@ -93,19 +93,19 @@ START_TEST(test_save_friend)
|
|||
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);
|
||||
TOX_PASS_KEY key;
|
||||
memcpy(key.salt, salt, 32);
|
||||
memcpy(key.key, known_key2, crypto_box_BEFORENMBYTES);
|
||||
size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
uint8_t encdata2[size2];
|
||||
ret = tox_pass_key_encrypt(data2, size, key, encdata2, &error1);
|
||||
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");
|
||||
|
||||
uint8_t out1[size], out2[size];
|
||||
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);
|
||||
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");
|
||||
|
||||
|
@ -130,13 +130,13 @@ START_TEST(test_keys)
|
|||
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);
|
||||
TOX_PASS_KEY key;
|
||||
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];
|
||||
ret = tox_pass_key_encrypt(string, 44, key, encrypted, &encerr);
|
||||
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];
|
||||
|
@ -146,12 +146,12 @@ START_TEST(test_keys)
|
|||
uint8_t out1[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
|
||||
uint8_t out2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
|
||||
|
||||
ret = tox_pass_key_decrypt(encrypted, 44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH, key, out1, &decerr);
|
||||
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");
|
||||
|
||||
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(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
|
||||
|
@ -161,10 +161,10 @@ START_TEST(test_keys)
|
|||
|
||||
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);
|
||||
TOX_PASS_KEY key2;
|
||||
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");
|
||||
ck_assert_msg(0 == memcmp(&key, &key2, sizeof(TOX_PASS_KEY)), "salt comparison failed");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "toxencryptsave.h"
|
||||
#include "defines.h"
|
||||
#include "../toxcore/crypto_core.h"
|
||||
#include "../toxcore/tox.h"
|
||||
#define SET_ERROR_PARAMETER(param, x) {if(param) {*param = x;}}
|
||||
|
||||
#ifdef VANILLA_NACL
|
||||
|
@ -41,8 +40,8 @@
|
|||
#error TOX_PASS_SALT_LENGTH is assumed to be equal to crypto_pwhash_scryptsalsa208sha256_SALTBYTES
|
||||
#endif
|
||||
|
||||
#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)
|
||||
#if TOX_PASS_KEY_LENGTH != crypto_box_KEYBYTES
|
||||
#error TOX_PASS_KEY_LENGTH is assumed to be equal to crypto_box_KEYBYTES
|
||||
#endif
|
||||
|
||||
#if TOX_PASS_ENCRYPTION_EXTRA_LENGTH != (crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH)
|
||||
|
@ -83,7 +82,8 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt)
|
|||
*
|
||||
* returns true on success
|
||||
*/
|
||||
bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error)
|
||||
bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *out_key,
|
||||
TOX_ERR_KEY_DERIVATION *error)
|
||||
{
|
||||
uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
randombytes(salt, sizeof salt);
|
||||
|
@ -91,9 +91,9 @@ bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out
|
|||
}
|
||||
|
||||
/* Same as above, except with use the given salt for deterministic key derivation.
|
||||
* The salt must be tox_salt_length() bytes in length.
|
||||
* The salt must be TOX_PASS_SALT_LENGTH bytes in length.
|
||||
*/
|
||||
bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key,
|
||||
bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key,
|
||||
TOX_ERR_KEY_DERIVATION *error)
|
||||
{
|
||||
if (pplength == 0 || !passphrase || !salt || !out_key) {
|
||||
|
@ -120,8 +120,8 @@ bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *sal
|
|||
}
|
||||
|
||||
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);
|
||||
memcpy(out_key->salt, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
memcpy(out_key->key, key, crypto_box_KEYBYTES);
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_KEY_DERIVATION_OK);
|
||||
return 1;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *sal
|
|||
*
|
||||
* returns true on success
|
||||
*/
|
||||
bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out,
|
||||
bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out,
|
||||
TOX_ERR_ENCRYPTION *error)
|
||||
{
|
||||
if (data_len == 0 || !data || !key || !out) {
|
||||
|
@ -155,8 +155,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
|
|||
out += TOX_ENC_SAVE_MAGIC_LENGTH;
|
||||
|
||||
/* then add the rest prefix */
|
||||
memcpy(out, key, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
|
||||
memcpy(out, key->salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
|
||||
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
|
@ -165,7 +164,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
|
|||
out += crypto_box_NONCEBYTES;
|
||||
|
||||
/* now encrypt */
|
||||
if (encrypt_data_symmetric(key, nonce, data, data_len, out)
|
||||
if (encrypt_data_symmetric(key->key, nonce, data, data_len, out)
|
||||
!= data_len + crypto_box_MACBYTES) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_ENCRYPTION_FAILED);
|
||||
return 0;
|
||||
|
@ -184,10 +183,10 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
|
|||
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_PASS_KEY key;
|
||||
TOX_ERR_KEY_DERIVATION _error;
|
||||
|
||||
if (!tox_derive_key_from_pass(passphrase, pplength, key, &_error)) {
|
||||
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) {
|
||||
|
@ -197,7 +196,7 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return tox_pass_key_encrypt(data, data_len, key, out, error);
|
||||
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
|
||||
|
@ -207,7 +206,7 @@ bool tox_pass_encrypt(const uint8_t *data, size_t data_len, uint8_t *passphrase,
|
|||
*
|
||||
* returns true on success
|
||||
*/
|
||||
bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out,
|
||||
bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out,
|
||||
TOX_ERR_DECRYPTION *error)
|
||||
{
|
||||
if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH) {
|
||||
|
@ -215,25 +214,27 @@ bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!data || !key || !out) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL);
|
||||
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;
|
||||
data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // salt only affects key derivation
|
||||
|
||||
size_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
|
||||
//uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
|
||||
//memcpy(salt, data, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
key += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; // ignore the salt, which is only needed for kdf
|
||||
data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
memcpy(nonce, data, crypto_box_NONCEBYTES);
|
||||
data += crypto_box_NONCEBYTES;
|
||||
|
||||
/* decrypt the data */
|
||||
if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out)
|
||||
if (decrypt_data_symmetric(key->key, nonce, data, decrypt_length + crypto_box_MACBYTES, out)
|
||||
!= decrypt_length) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_FAILED);
|
||||
return 0;
|
||||
|
@ -254,33 +255,34 @@ bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key
|
|||
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 (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH || pplength == 0) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_INVALID_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!data || !passphrase || !out) {
|
||||
SET_ERROR_PARAMETER(error, TOX_ERR_DECRYPTION_NULL);
|
||||
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;
|
||||
}
|
||||
|
||||
uint8_t passkey[crypto_hash_sha256_BYTES];
|
||||
crypto_hash_sha256(passkey, passphrase, pplength);
|
||||
|
||||
uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
memcpy(salt, data + TOX_ENC_SAVE_MAGIC_LENGTH, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
|
||||
/* derive the key */
|
||||
uint8_t key[crypto_box_KEYBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
|
||||
TOX_PASS_KEY key;
|
||||
|
||||
if (crypto_pwhash_scryptsalsa208sha256(
|
||||
key + crypto_pwhash_scryptsalsa208sha256_SALTBYTES,
|
||||
crypto_box_KEYBYTES, (char *)passkey, sizeof(passkey), salt,
|
||||
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE * 2, /* slightly stronger */
|
||||
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) {
|
||||
if (!tox_derive_key_with_salt(passphrase, pplength, salt, &key, NULL)) {
|
||||
/* out of memory most likely */
|
||||
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, 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)
|
||||
|
|
|
@ -39,7 +39,7 @@ struct Tox_Options;
|
|||
#endif
|
||||
|
||||
#define TOX_PASS_SALT_LENGTH 32
|
||||
#define TOX_PASS_KEY_LENGTH 64
|
||||
#define TOX_PASS_KEY_LENGTH 32
|
||||
#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH 80
|
||||
|
||||
/* This module is conceptually organized into two parts. The first part are the functions
|
||||
|
@ -60,6 +60,15 @@ struct Tox_Options;
|
|||
* Ditto if they forget their password, there is no way to recover the data.
|
||||
*/
|
||||
|
||||
/* Since apparently no one actually bothered to learn about the module previously,
|
||||
* the recently removed functions tox_encrypted_new and tox_get_encrypted_savedata
|
||||
* may be trivially replaced by calls to tox_pass_decrypt -> tox_new or
|
||||
* tox_get_savedata -> tox_pass_encrypt as appropriate. The removed functions
|
||||
* were never more than 5 line wrappers of the other public API functions anyways.
|
||||
* (As has always been, tox_pass_decrypt and tox_pass_encrypt are interchangeable
|
||||
* with tox_pass_key_decrypt and tox_pass_key_encrypt, as the client program requires.)
|
||||
*/
|
||||
|
||||
typedef enum TOX_ERR_KEY_DERIVATION {
|
||||
TOX_ERR_KEY_DERIVATION_OK,
|
||||
/**
|
||||
|
@ -155,6 +164,14 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, s
|
|||
* intensive than part one. The first 3 functions are for key handling.
|
||||
*/
|
||||
|
||||
/* This key structure's internals should not be used by any client program, even
|
||||
* if they are straightforward here.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t salt[TOX_PASS_SALT_LENGTH];
|
||||
uint8_t key[TOX_PASS_KEY_LENGTH];
|
||||
} TOX_PASS_KEY;
|
||||
|
||||
/* 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.
|
||||
|
@ -166,12 +183,13 @@ bool tox_pass_decrypt(const uint8_t *data, size_t length, uint8_t *passphrase, s
|
|||
*
|
||||
* returns true on success
|
||||
*/
|
||||
bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, uint8_t *out_key, TOX_ERR_KEY_DERIVATION *error);
|
||||
bool tox_derive_key_from_pass(uint8_t *passphrase, size_t pplength, TOX_PASS_KEY *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.
|
||||
/* Same as above, except use the given salt for deterministic key derivation.
|
||||
* The salt must be TOX_PASS_SALT_LENGTH bytes in length.
|
||||
*/
|
||||
bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, uint8_t *out_key,
|
||||
bool tox_derive_key_with_salt(uint8_t *passphrase, size_t pplength, uint8_t *salt, TOX_PASS_KEY *out_key,
|
||||
TOX_ERR_KEY_DERIVATION *error);
|
||||
|
||||
/* This retrieves the salt used to encrypt the given data, which can then be passed to
|
||||
|
@ -194,7 +212,7 @@ bool tox_get_salt(const uint8_t *data, uint8_t *salt);
|
|||
*
|
||||
* returns true on success
|
||||
*/
|
||||
bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *key, uint8_t *out,
|
||||
bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const TOX_PASS_KEY *key, uint8_t *out,
|
||||
TOX_ERR_ENCRYPTION *error);
|
||||
|
||||
/* This is the inverse of tox_pass_key_encrypt, also using only keys produced by
|
||||
|
@ -204,7 +222,7 @@ bool tox_pass_key_encrypt(const uint8_t *data, size_t data_len, const uint8_t *k
|
|||
*
|
||||
* returns true on success
|
||||
*/
|
||||
bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const uint8_t *key, uint8_t *out,
|
||||
bool tox_pass_key_decrypt(const uint8_t *data, size_t length, const TOX_PASS_KEY *key, uint8_t *out,
|
||||
TOX_ERR_DECRYPTION *error);
|
||||
|
||||
/* Determines whether or not the given data is encrypted (by checking the magic number)
|
||||
|
|
Loading…
Reference in New Issue
Block a user