Lots of Updates
This commit is contained in:
parent
7b772b8031
commit
3259b1bd53
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
22
src/risk.md
22
src/risk.md
|
@ -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
|
||||
|
|
34
src/tapir.md
34
src/tapir.md
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue