Add new attachment encrypt/decrypt functions #65
+914
−3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This defines a new determinstic, streamable attachment encryption/decryption for Session clients to use in the future, built on libsodium's crypto_secretstream API (which is XChaCha20-poly1305-based).
Unlike current Session attachment encryption, the encryption added here uses deterministic (though private, cryptographically secure) nonce and key generated from the user, file contents itself, and type of file, so that the same user uploading an identical attachment results in an identical encrypted copy, thus allowing deduplication in case of things like file server response timeouts or repeated uploads of the same profile picture.
Unlike current attachments, these functions also allow streaming of attachment data (via the added Decryptor) so that, in future clients, an attachment can be decrypted and saved as it arrives, rather than needing to store the whole thing in memory to decrypt it.
This also reimplements the padding added to attachments. Currently clients use this monstrosity:
which is not only difficult to read, but also involves several floating point functions where imprecision (and thus potential metadata leakage about which client created it) can creep in. The new protocol works vaguely similar: we pad up to fixed sizes that with the size of the attachment.
Moreover there is no way to recover the amount of padding from the attachment itself: rather a Session client has to communicate the URL, key, and size to someone they are trying to send to out of band, who then downloads, decrypts the whole thing, then chops off the padding based on what they were told the size was. With the new scheme, padding is now deterministic and embedded in the pre-encrypted data, and is transparently stripped out when decrypting.
The plan is for Session clients to start understanding (but not using) this new encryption format, and then once sufficient time has passed for clients to have upgraded, start using this instead of the current AES-GCM encryption.