summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordubslow <bunslow@gmail.com>2014-10-08 18:14:23 -0500
committerdubslow <bunslow@gmail.com>2014-10-08 18:50:40 -0500
commite6f30694d32a81f9171b2057d9c873cc16f6dca1 (patch)
tree198d595c26c7eb714e6f032d43638dd9408c9bea
parenteee37b5767488b8d21c0fb918ae8bf974e66d27d (diff)
refactor toxencryptedsave to allow passphrase encryption of arbitrary data
also a minor API change for clarity
-rw-r--r--auto_tests/encryptsave_test.c2
-rw-r--r--toxencryptsave/toxencryptsave.c97
-rw-r--r--toxencryptsave/toxencryptsave.h24
3 files changed, 87 insertions, 36 deletions
diff --git a/auto_tests/encryptsave_test.c b/auto_tests/encryptsave_test.c
index 7661cbc7..752f906f 100644
--- a/auto_tests/encryptsave_test.c
+++ b/auto_tests/encryptsave_test.c
@@ -65,7 +65,7 @@ START_TEST(test_save_friend)
65 uint8_t data[size]; 65 uint8_t data[size];
66 test = tox_encrypted_save(tox1, data, "correcthorsebatterystaple", 25); 66 test = tox_encrypted_save(tox1, data, "correcthorsebatterystaple", 25);
67 ck_assert_msg(test == 0, "failed to encrypted save"); 67 ck_assert_msg(test == 0, "failed to encrypted save");
68 ck_assert_msg(tox_is_data_encrypted(data) == 1, "magic number missing"); 68 ck_assert_msg(tox_is_save_encrypted(data) == 1, "magic number missing");
69 Tox *tox3 = tox_new(0); 69 Tox *tox3 = tox_new(0);
70 test = tox_encrypted_load(tox3, data, size, "correcthorsebatterystaple", 25); 70 test = tox_encrypted_load(tox3, data, size, "correcthorsebatterystaple", 25);
71 ck_assert_msg(test == 0, "failed to encrypted load"); 71 ck_assert_msg(test == 0, "failed to encrypted load");
diff --git a/toxencryptsave/toxencryptsave.c b/toxencryptsave/toxencryptsave.c
index 070f0184..b018bd48 100644
--- a/toxencryptsave/toxencryptsave.c
+++ b/toxencryptsave/toxencryptsave.c
@@ -44,17 +44,16 @@
44/* return size of the messenger data (for encrypted saving). */ 44/* return size of the messenger data (for encrypted saving). */
45uint32_t tox_encrypted_size(const Tox *tox) 45uint32_t tox_encrypted_size(const Tox *tox)
46{ 46{
47 return tox_size(tox) + crypto_box_MACBYTES + crypto_box_NONCEBYTES 47 return tox_size(tox) + TOX_PASS_ENCRYPTION_EXTRA_LENGTH + TOX_ENC_SAVE_MAGIC_LENGTH;
48 + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + TOX_ENC_SAVE_MAGIC_LENGTH;
49} 48}
50 49
51/* Save the messenger data encrypted with the given password. 50/* Encrypts the given data with the given passphrase. The output array must be
52 * data must be at least tox_encrypted_size(). 51 * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
53 * 52 *
54 * returns 0 on success 53 * returns 0 on success
55 * returns -1 on failure 54 * returns -1 on failure
56 */ 55 */
57int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength) 56int tox_pass_encrypt(uint8_t* data, uint32_t data_len, uint8_t* passphrase, uint32_t pplength, uint8_t* out)
58{ 57{
59 if (pplength == 0) 58 if (pplength == 0)
60 return -1; 59 return -1;
@@ -79,15 +78,10 @@ int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint3
79 78
80 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ 79 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
81 80
82 /* next get plain save data */
83 uint32_t temp_size = tox_size(tox);
84 uint8_t temp_data[temp_size];
85 tox_save(tox, temp_data);
86
87 /* the output data consists of, in order: 81 /* the output data consists of, in order:
88 * magic number, salt, nonce, mac, enc_data 82 * salt, nonce, mac, enc_data
89 * where the mac is automatically prepended by the encrypt() 83 * where the mac is automatically prepended by the encrypt()
90 * the magic+salt+nonce is called the prefix 84 * the salt+nonce is called the prefix
91 * I'm not sure what else I'm supposed to do with the salt and nonce, since we 85 * I'm not sure what else I'm supposed to do with the salt and nonce, since we
92 * need them to decrypt the data 86 * need them to decrypt the data
93 */ 87 */
@@ -96,40 +90,56 @@ int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint3
96 uint8_t nonce[crypto_box_NONCEBYTES]; 90 uint8_t nonce[crypto_box_NONCEBYTES];
97 random_nonce(nonce); 91 random_nonce(nonce);
98 92
99 memcpy(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH); 93 memcpy(out, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
100 data += TOX_ENC_SAVE_MAGIC_LENGTH; 94 out += crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
101 memcpy(data, salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES); 95 memcpy(out, nonce, crypto_box_NONCEBYTES);
102 data += crypto_pwhash_scryptsalsa208sha256_SALTBYTES; 96 out += crypto_box_NONCEBYTES;
103 memcpy(data, nonce, crypto_box_NONCEBYTES);
104 data += crypto_box_NONCEBYTES;
105 97
106 /* now encrypt */ 98 /* now encrypt */
107 if (encrypt_data_symmetric(key, nonce, temp_data, temp_size, data) 99 if (encrypt_data_symmetric(key, nonce, data, data_len, out)
108 != temp_size + crypto_box_MACBYTES) { 100 != data_len + crypto_box_MACBYTES) {
109 return -1; 101 return -1;
110 } 102 }
111 103
112 return 0; 104 return 0;
113} 105}
114 106
115/* Load the messenger from encrypted data of size length. 107/* Save the messenger data encrypted with the given password.
108 * data must be at least tox_encrypted_size().
116 * 109 *
117 * returns 0 on success 110 * returns 0 on success
118 * returns -1 on failure 111 * returns -1 on failure
119 */ 112 */
120int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength) 113int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength)
121{ 114{
122 if (length <= crypto_box_MACBYTES + crypto_box_NONCEBYTES + crypto_pwhash_scryptsalsa208sha256_SALTBYTES + 115 /* first get plain save data */
123 TOX_ENC_SAVE_MAGIC_LENGTH) 116 uint32_t temp_size = tox_size(tox);
124 return -1; 117 uint8_t temp_data[temp_size];
125 118 tox_save(tox, temp_data);
126 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
127 return -1;
128 119
120 /* the output data consists of, in order: magic number, enc_data */
121 /* first add the magic number */
122 memcpy(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH);
129 data += TOX_ENC_SAVE_MAGIC_LENGTH; 123 data += TOX_ENC_SAVE_MAGIC_LENGTH;
130 124
131 uint32_t decrypt_length = length - crypto_box_MACBYTES - crypto_box_NONCEBYTES 125
132 - crypto_pwhash_scryptsalsa208sha256_SALTBYTES - TOX_ENC_SAVE_MAGIC_LENGTH; 126 /* now encrypt */
127 return tox_pass_encrypt(temp_data, temp_size, passphrase, pplength, data);
128}
129
130
131/* Decrypts the given data with the given passphrase. The output array must be
132 * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
133 *
134 * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success
135 * returns -1 on failure
136 */
137int tox_pass_decrypt(const uint8_t* data, uint32_t length, uint8_t* passphrase, uint32_t pplength, uint8_t* out)
138{
139 if (length <= TOX_PASS_ENCRYPTION_EXTRA_LENGTH)
140 return -1;
141
142 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
133 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; 143 uint8_t salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES];
134 uint8_t nonce[crypto_box_NONCEBYTES]; 144 uint8_t nonce[crypto_box_NONCEBYTES];
135 145
@@ -155,13 +165,32 @@ int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *
155 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */ 165 sodium_memzero(passkey, crypto_hash_sha256_BYTES); /* wipe plaintext pw */
156 166
157 /* decrypt the data */ 167 /* decrypt the data */
158 uint8_t temp_data[decrypt_length]; 168 if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, out)
159
160 if (decrypt_data_symmetric(key, nonce, data, decrypt_length + crypto_box_MACBYTES, temp_data)
161 != decrypt_length) { 169 != decrypt_length) {
162 return -1; 170 return -1;
163 } 171 }
164 172
173 return decrypt_length;
174}
175
176/* Load the messenger from encrypted data of size length.
177 *
178 * returns 0 on success
179 * returns -1 on failure
180 */
181int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength)
182{
183 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) != 0)
184 return -1;
185 data += TOX_ENC_SAVE_MAGIC_LENGTH; length -= TOX_ENC_SAVE_MAGIC_LENGTH;
186
187 uint32_t decrypt_length = length - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
188 uint8_t temp_data[decrypt_length];
189
190 if (tox_pass_decrypt(data, length, passphrase, pplength, temp_data)
191 != decrypt_length)
192 return -1;
193
165 return tox_load(tox, temp_data, decrypt_length); 194 return tox_load(tox, temp_data, decrypt_length);
166} 195}
167 196
@@ -170,7 +199,7 @@ int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *
170 * returns 1 if it is encrypted 199 * returns 1 if it is encrypted
171 * returns 0 otherwise 200 * returns 0 otherwise
172 */ 201 */
173int tox_is_data_encrypted(const uint8_t *data) 202int tox_is_save_encrypted(const uint8_t *data)
174{ 203{
175 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) 204 if (memcmp(data, TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0)
176 return 1; 205 return 1;
diff --git a/toxencryptsave/toxencryptsave.h b/toxencryptsave/toxencryptsave.h
index 75094a2b..e3f998af 100644
--- a/toxencryptsave/toxencryptsave.h
+++ b/toxencryptsave/toxencryptsave.h
@@ -35,6 +35,8 @@ extern "C" {
35typedef struct Tox Tox; 35typedef struct Tox Tox;
36#endif 36#endif
37 37
38#define TOX_PASS_ENCRYPTION_EXTRA_LENGTH (crypto_box_MACBYTES + crypto_box_NONCEBYTES \
39 + crypto_pwhash_scryptsalsa208sha256_SALTBYTES)
38 40
39/* This "module" provides functions analogous to tox_load and tox_save in toxcore 41/* This "module" provides functions analogous to tox_load and tox_save in toxcore
40 * Clients should consider alerting their users that, unlike plain data, if even one bit 42 * Clients should consider alerting their users that, unlike plain data, if even one bit
@@ -45,6 +47,16 @@ typedef struct Tox Tox;
45/* return size of the messenger data (for encrypted saving). */ 47/* return size of the messenger data (for encrypted saving). */
46uint32_t tox_encrypted_size(const Tox *tox); 48uint32_t tox_encrypted_size(const Tox *tox);
47 49
50/* Encrypts the given data with the given passphrase. The output array must be
51 * at least data_len + TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
52 *
53 * tox_encrypted_save() is a good example of how to use this function.
54 *
55 * returns 0 on success
56 * returns -1 on failure
57 */
58int tox_pass_encrypt(uint8_t* data, uint32_t data_len, uint8_t* passphrase, uint32_t pplength, uint8_t* out);
59
48/* Save the messenger data encrypted with the given password. 60/* Save the messenger data encrypted with the given password.
49 * data must be at least tox_encrypted_size(). 61 * data must be at least tox_encrypted_size().
50 * 62 *
@@ -53,6 +65,16 @@ uint32_t tox_encrypted_size(const Tox *tox);
53 */ 65 */
54int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength); 66int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength);
55 67
68/* Decrypts the given data with the given passphrase. The output array must be
69 * at least data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH bytes long.
70 *
71 * tox_encrypted_load() is a good example of how to use this function.
72 *
73 * returns the length of the output data (== data_len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH) on success
74 * returns -1 on failure
75 */
76int tox_pass_decrypt(const uint8_t* data, uint32_t length, uint8_t* passphrase, uint32_t pplength, uint8_t* out);
77
56/* Load the messenger from encrypted data of size length. 78/* Load the messenger from encrypted data of size length.
57 * 79 *
58 * returns 0 on success 80 * returns 0 on success
@@ -65,7 +87,7 @@ int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *
65 * returns 1 if it is encrypted 87 * returns 1 if it is encrypted
66 * returns 0 otherwise 88 * returns 0 otherwise
67 */ 89 */
68int tox_is_data_encrypted(const uint8_t *data); 90int tox_is_save_encrypted(const uint8_t *data);
69 91
70#ifdef __cplusplus 92#ifdef __cplusplus
71} 93}