-
Notifications
You must be signed in to change notification settings - Fork 8
Add new attachment encrypt/decrypt functions #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jagerman
wants to merge
2
commits into
session-foundation:dev
Choose a base branch
from
jagerman:new-attach-encrypt
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+2,118
−14
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: let desiredSize: Int = max(541, min(Int(Network.maxFileSize), Int(floor(pow(1.05, ceil(log(Double(plaintext.count)) / log(1.05))))))) 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.
6e25362
to
0f8a7f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need a C API to support iOS sorry 🥲
I've updated this with a whole bunch of overloads for different combinations of en/decryption to/from vector/buffer/file, and added C API wrappers for the most loved platform of all. |
29b421c
to
aa32593
Compare
Actually added the C header this time. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.