Lots of Updates

This commit is contained in:
Sarah Jamie Lewis 2020-11-27 14:03:30 -08:00
parent 7b772b8031
commit 3259b1bd53
6 changed files with 109 additions and 33 deletions

View File

@ -5,9 +5,12 @@
- [Open Questions](./open-questions.md)
- [Connectivity](./connectivity.md)
- [Tapir](./tapir.md)
- [Packet Format](./packet_format.md)md
- [Authentication Protocol](./authentication_protocol.md)
- [Cwtch Library](./cwtch.md)
- [Groups](./groups.md)
- [Cwtch UI](./ui.md)
- [Profile Encryption & Storage](./profile_encryption_and_storage.md)
- [Cwtch Server](./server.md)
- [Development](./development.md)
- [Deployment](./deployment.md)

View File

@ -0,0 +1,51 @@
# Authentication Protocol
Each peer, given an open connection \\(C\\):
\\[ \\
I = \mathrm{InitializeIdentity()} \\\\
I_e = \mathrm{InitializeEphemeralIdentity()} \\\\
\\\\
I,I_e \rightarrow C \\\\
P,P_e \leftarrow C \\\\
\\\\
k = \mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\\\
c = \mathrm{E}(k, transcript.Commit()) \\\\
c \rightarrow C \\\\
c_p \leftarrow C \\\\
\mathrm{D}(k, c_p) \stackrel{?}{=} transcript.LatestCommit() \\\\
\\]
The above represents a sketch protocol, in reality there are a few
implementation details worth pointing out:
Once derived from the key derivation function \\(\mathrm{KDF}\\\) the key
\\(k\\) is set *on* the connection, meaning the authentication app doesn't
do the encryption or decryption explicitly.
Also the concatenation of parts of the 3DH exchange is strictly ordered:
* DH of the Long term identity of the outbound connection by the ephemeral
key of the inbound connection.
* DH of the Long term identity of the inbound connection by the ephemeral
key of the outbound connection.
* DH of the two ephemeral identities of the inbound and outbound connections.
This strict ordering ensures both sides of the connection derive the *same*
session key.
### Cryptographic Properties
During an online-session, all messages encrypted with the session key can be authenticated by the peers as having come
from their peer (or at least, someone with possession of their peers secret key as it related to their onion address).
Once the session has ended, a transcript containing the long term and ephemeral public keys, a derived session key and
all encrypted messages in the session cannot be proven to be authentic i.e. this protocol provides message & participant
repudiation (offline deniable) in addition to message unlinkability (offline deniable) in the case where someone is satisfied
that a single message in the transcript must have originated from a peer, there is no way of linking any other message to
the session.
Intuition for the above: the only cryptographic material related to the transcript is the derived session key - if the
session key is made public it can be used to forge new messages in the transcript - and as such, any standalone
transcript is subject to forgery and thus cannot be used to cryptographically tie a peer to a conversation.

12
src/packet_format.md Normal file
View File

@ -0,0 +1,12 @@
# Packet Format
All tapir packets are fixed length (8192 bytes) with the first 2 bytes indicated the actual length of the message,
`len` bytes of data, and the rest zero padded:
| len (2 bytes) | data (len bytes) | paddding (8190-len bytes)|
Once encrypted, the entire 8192 byte data packet is encrypted using [libsodium secretbox](https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox) using the standard structure (
note in this case the actual usable size of the data packet is 8190-14 to accommodate the nonce included by secret box)
For information on how th secret key is derived see the [authentication protocol](./authentication_protocol.md)

View File

@ -0,0 +1,20 @@
# Profile Encryption & Storage
Profiles are stored on locally on disk and encrypted using a key derived from user-known password (via pbkdf2).
Note that once encrypted and stored on disk, the only way to recover a profile is by rederiving the password - as such
it isn't possible to provide a full list of profiles a user might have access to until they enter a password.
## Unencrypted Profiles and the Default Password
To handle profiles that are "unencrypted" (i.e don't require a password to open) we currently create a profile
with a [default, hardcoded password](https://git.openprivacy.ca/cwtch.im/ui/src/branch/master/go/the/globals.go#L12).
This isn't ideal, we would much rather wish to rely on OS-provided key material such that the profile is bound to a
specific device, but such features are currently patchwork - we also note by creating an unencrypted profile, people
who use Cwtch are explicitly opting into the risk that someone with access to the file system may be able to decrypt
their profile.
### Related Code
https://git.openprivacy.ca/cwtch.im/cwtch/src/commit/3529e21b0e0763ca6ec20ddfd13e22c8070c4915/storage/v1/file_enc.go

View File

@ -56,6 +56,28 @@ Beyond individual conversations, we also seek to defend against context correlat
predictable. E.g. Alice calls Eve every Monday evening for around an hour.
### Active Attacks
#### Misrepresentation Attacks
Cwtch provides no global display name registry, and as such people using Cwtch are more vulnerable to attacks
based around misrepresentation i.e. people pretending to be other people:
A basic flow of one of these attacks is as follows, although other flows also exist:
- Alice has a friend named Bob and another called Eve
- Eve finds out Alice has a friend named Bob
- Eve creates thousands of new accounts to find one that has a similar picture / public key to Bob (won't be identical but might fool someone for a few minutes)
- Eve calls this new account "Eve New Account" and adds Alice as a friend.
- Eve then changes her name on "Eve New Account" to "Bob"
- Alice sends messages intended for "Bob" to Eve's fake Bob account
Because misrepresentation attacks are inherently about trust and verification the only absolute way of preventing them
is for users to absolutely validate the public key. This is obviously not-ideal and in many cases simply *won't-happen*.
As such we aim to provide some user-experiance hints in the [ui](./ui.md) to guide people in making choices around whether
to trust accounts and/or to distinguish accounts that may be attempting to represent themselves as other users.
## A note on Physical Attacks
Cwtch does not consider attacks that require physical access (or equivalent) to

View File

@ -48,42 +48,10 @@ Initializes a [Merlin](https://merlin.cool)-based cryptographic transcript that
* **Capabilities Granted**: *AuthenticationCapability*
* **Capabilities Required**: *None*
Engages in an ephemeral triple-diffie-hellman handshake to derive a unique,
Engages in an [ephemeral triple-diffie-hellman handshake](./authentication_protocol.md) to derive a unique,
authenticated session key.
Each peer, given an open connection \\(C\\):
\\[ \\
I = \mathrm{InitializeIdentity()} \\\\
I_e = \mathrm{InitializeEphemeralIdentity()} \\\\
\\\\
I,I_e \rightarrow C \\\\
P,P_e \leftarrow C \\\\
\\\\
k = \mathrm{KDF}({P_e}^{i} + {P}^{i_e} + {P_e}^{i_e}) \\\\
c = \mathrm{E}(k, transcript.Commit()) \\\\
c \rightarrow C \\\\
c_p \leftarrow C \\\\
\mathrm{D}(k, c_p) \stackrel{?}{=} transcript.LatestCommit() \\\\
\\]
The above represents a sketch protocol, in reality there are a few
implementation details worth pointing out:
Once derived from the key deriviation function \\(\mathrm{KDF}\\\) the key
\\(k\\) is set *on* the connection, meaning the authentication app doesn't
do the encryption or decryption explicitly.
Also the concatenation of parts of the 3DH exchange is strictly ordered:
* DH of the Long term identity of the outbound connection by the ephemeral
key of the inbound connection.
* DH of the Long term identity of the inbound connection by the ephemeral
key of the outbound connection.
* DH of the two ephemeral identities of the inbound and outbound connections.
This strict ordering ensures both sides of the connection derive the *same*
session key.
### transcript.Commit()