diff options
author | dubslow <bunslow@gmail.com> | 2014-10-08 18:14:23 -0500 |
---|---|---|
committer | dubslow <bunslow@gmail.com> | 2014-10-08 18:50:40 -0500 |
commit | e6f30694d32a81f9171b2057d9c873cc16f6dca1 (patch) | |
tree | 198d595c26c7eb714e6f032d43638dd9408c9bea /toxencryptsave/toxencryptsave.c | |
parent | eee37b5767488b8d21c0fb918ae8bf974e66d27d (diff) |
refactor toxencryptedsave to allow passphrase encryption of arbitrary data
also a minor API change for clarity
Diffstat (limited to 'toxencryptsave/toxencryptsave.c')
-rw-r--r-- | toxencryptsave/toxencryptsave.c | 97 |
1 files changed, 63 insertions, 34 deletions
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). */ |
45 | uint32_t tox_encrypted_size(const Tox *tox) | 45 | uint32_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 | */ |
57 | int tox_encrypted_save(const Tox *tox, uint8_t *data, uint8_t *passphrase, uint32_t pplength) | 56 | int 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 | */ |
120 | int tox_encrypted_load(Tox *tox, const uint8_t *data, uint32_t length, uint8_t *passphrase, uint32_t pplength) | 113 | int 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 | */ | ||
137 | int 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 | */ | ||
181 | int 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 | */ |
173 | int tox_is_data_encrypted(const uint8_t *data) | 202 | int 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; |