Commit graph

40 commits

Author SHA1 Message Date
Guus Sliepen
dece2db78e Don't log seqno failures in sptps_verify_datagram().
This function is not used for normal traffic, only when a packet from an
unknown source is received and we need to check against candidates. No
failures should be logger in this case; if the packet is really not
valid this will be logged by handle_incoming_vpn_data().
2015-05-19 21:32:30 +02:00
Etienne Dechamps
aa52300b2b Trivial: make sptps_receive_data_datagram() a little more readable.
The new code updates variables as stuff is being consumed, so that the
reader doesn't have to do that in his head.
2015-05-17 17:52:15 +01:00
Etienne Dechamps
d237efd325 Only read one record at a time in sptps_receive_data().
sptps_receive_data() always consumes the entire buffer passed to it,
which is somewhat inflexible. This commit improves the interface so that
sptps_receive_data() consumes at most one record. The goal is to allow
non-SPTPS stuff to be interleaved with SPTPS records in a single TCP
stream.
2015-05-10 21:08:57 +01:00
Etienne Dechamps
2e7f68ad2b Don't abort() willy-nilly in SPTPS code.
If receive_handshake() or the receive_record() user callback returns an
error, sptps_receive_data_datagram() crashes the entire process. This is
heavy-handed, makes tinc very brittle to certain failures (i.e.
unexpected packets), and is inconsistent with the rest of SPTPS code.
2015-03-08 17:35:06 +00:00
Guus Sliepen
107d9c7da5 Use void pointers for opaque data blobs in the SPTPS code. 2014-12-24 22:15:40 +01:00
Etienne Dechamps
ddd0cd47bc Verify seqno early in sptps_verify_datagram().
This is a slight optimization for sptps_verify_datagram(), which might
come in handy since this function is called in a loop via try_harder().

It turns out that since sptps_verify_datagram() doesn't update any
state, it doesn't matter in which order verifications are done. However,
it does affect performance since it's much cheaper to check the seqno
than to try to decrypt the packet.

Since this function is called with the wrong node most of the time, it
makes verification vastly faster for the majority of calls because the
seqno will be wrong in most cases.
2014-07-12 22:16:57 +02:00
Etienne Dechamps
b54fde6747 Implement sptps_verify_datagram().
Implementation of sptps_verify_datagram() was left as a TODO. This
causes problems when using SPTPS in tinc, because this function is
used in try_mac(), which itself is used in try_harder() to locate
nodes sending UDP packets from unexpected addresses. In the current
state this function always returns true, resulting in UDP addresses
of random nodes getting changed which makes UDP communication
fragile and unreliable. In addition, this makes UDP communication
impossible through port translation and local discovery.

This commit adds the missing implementation, thus fixing the issue.
2014-06-29 16:48:57 +01:00
Guus Sliepen
f0e7e6b03e Rename ECDSA to Ed25519. 2014-05-18 20:47:04 +02:00
Guus Sliepen
2980173ee7 Use the ChaCha-Poly1305 cipher for the SPTPS protocol.
The main reason to switch from AES-256-GCM to ChaCha-Poly1305 is to remove a
dependency on OpenSSL, whose behaviour of the AES-256-GCM decryption function
changes between versions. The source code for ChaCha-Pol1305 is small and in
the public domain, and can therefore be easily included in tinc itself.
Moreover, it is very fast even without using any optimized assembler, easily
outperforming AES-256-GCM on platforms that don't have special AES instructions
in hardware.
2014-04-14 21:43:45 +02:00
Guus Sliepen
0da0728088 Use AES-256-GCM for the SPTPS protocol.
It is faster than AES-256-CTR + HMAC-SHA256, especially on Intel chips with AES
and PCLMULQDQ instructions.
2013-10-13 01:02:52 +02:00
Guus Sliepen
ccbf70b66f Fix the replay window in SPTPS. 2013-08-30 14:22:05 +02:00
Sven-Haegar Koch
a518f82af7 Modified some error messages in src/sptps.c. 2013-05-15 13:53:13 +02:00
Guus Sliepen
fa20cfceec Don't try to handle incoming data if sptps_start() has not been called yet. 2013-05-12 13:39:22 +02:00
Guus Sliepen
d03dc91e27 Don't free ephemeral ECDH keys twice.
ecdh_compute_shared() was changed to immediately delete the ephemeral key after
the shared secret was computed.  Therefore, the pointer to the ecdh_t struct
should be zeroed so it won't be freed again when a struct sptps_t is freed.
2013-05-11 14:14:20 +02:00
Guus Sliepen
214060ef20 Fix warnings for functions marked __attribute((warn_unused_result)). 2013-05-10 20:30:47 +02:00
Guus Sliepen
9b9230a0a7 Use conditional compilation for cryptographic functions.
This gets rid of the rest of the symbolic links. However, as a consequence, the
crypto header files have now moved to src/, and can no longer contain
library-specific declarations. Therefore, cipher_t, digest_t, ecdh_t, ecdsa_t
and rsa_t are now all opaque types, and only pointers to those types can be
used.
2013-05-01 17:17:22 +02:00
Guus Sliepen
3a039ece25 Fix datagram SPTPS.
Commit dd07c9fc1f broke the reception of datagram
SPTPS packets, by undoing the conversion of the sequence number to host byte
order before comparison. This caused error messages like "Packet is 16777215
seqs in the future, dropped (1)".
2013-01-21 13:47:46 +01:00
Guus Sliepen
cc3c69c892 Releasing 1.1pre5. 2013-01-20 21:03:22 +01:00
Guus Sliepen
eef25266cb Count the number of correctly received UDP packets.
Keep track of the number of correct, non-replayed UDP packets that have been
received, regardless of their content. This can be compared to the sequence
number to determine the real packet loss.
2013-01-15 13:33:16 +01:00
Guus Sliepen
dd07c9fc1f Check HMAC before sequence number. 2013-01-14 13:08:35 +01:00
Guus Sliepen
40ed0c07dd Log more messages using logger(). 2012-10-14 15:37:24 +02:00
Sven-Haegar Koch
ec1f7e525d sptps.c: Add missing newline to log message. 2012-10-12 17:19:56 +02:00
Guus Sliepen
d917c8cb6b Fix whitespace. 2012-10-10 17:17:49 +02:00
Guus Sliepen
d1ec010660 Fix memory leaks found by valgrind. 2012-10-09 16:27:28 +02:00
Guus Sliepen
5d0812d492 Remove a debug message. 2012-10-07 14:06:47 +02:00
Guus Sliepen
47f33e07ff Fix off-by-one error.
Apart from writing 1 byte beyond an array allocated on the stack, this slipped
an unitialized byte in the seed used for key generation.
2012-10-06 16:53:43 +02:00
Guus Sliepen
6bc8df3e01 Add Brandon Black's replay window code to SPTPS. 2012-07-31 20:39:15 +02:00
Guus Sliepen
5ede437307 Handle SPTPS datagrams in try_mac(). 2012-07-31 20:36:35 +02:00
Guus Sliepen
153abaa4d9 Use datagram SPTPS for packet exchange between nodes.
When two nodes which support SPTPS want to send packets to each other, they now
always use SPTPS. The node initiating the SPTPS session send the first SPTPS
packet via an extended REQ_KEY messages. All other handshake messages are sent
using ANS_KEY messages. This ensures that intermediate nodes using an older
version of tinc can still help with NAT traversal. After the authentication
phase is over, SPTPS packets are sent via UDP, or are encapsulated in extended
REQ_KEY messages instead of PACKET messages.
2012-07-30 18:36:59 +02:00
Sven-Haegar Koch
a5bb6d40fb sptps_stop(): clear pointers after free to avoid double free.
sptps_stop() may get called twice on some failed connection setups.
2012-04-15 01:10:49 +02:00
Guus Sliepen
d7bf63c63a Make sure the signature also covers the session label. 2012-03-18 21:24:46 +01:00
Guus Sliepen
d756bb92ed Don't send an ACK message after the first key exchange in the SPTPS protocol. 2012-03-18 17:46:30 +01:00
Guus Sliepen
3a4fe104a0 Add datagram mode to the SPTPS protocol.
* Everything is identical except the headers of the records.
* Instead of sending explicit message length and having an implicit sequence
  number, datagram mode has an implicit message length and an explicit sequence
  number.
* The sequence number is used to set the most significant bytes of the counter.
2012-03-18 16:42:02 +01:00
Guus Sliepen
84570275ac Ensure all SPTPS functions are prefixed with sptps_. 2012-02-26 12:33:16 +01:00
Guus Sliepen
65d6f023c4 Use SPTPS when ExperimentalProtocol is enabled. 2012-02-25 18:25:21 +01:00
Guus Sliepen
efd21e232d Apply HMAC after encryption. 2012-02-25 15:18:15 +01:00
Guus Sliepen
2a9060bba6 Exchange ACK records to indicate switch to new keys.
This allow application records to be sent while key renegotiation is still
happening.
2011-10-06 15:32:12 +02:00
Guus Sliepen
3b5898078a Use counter mode encryption. 2011-10-06 09:34:34 +02:00
Guus Sliepen
3001351150 Update SPTPS protocol.
* Exchange nonce and ECDH public key first, calculate the ECDSA signature
  over the complete key exchange.
* Make an explicit distinction between client and server in the signatures.
* Add more comments and replace some magic numbers by #defines.

Thanks to Erik Tews for very helpful hints and comments!
2011-10-05 22:00:51 +02:00
Guus Sliepen
3d75dbc088 Start of "Simple Peer-To-Peer Security" protocol.
Encryption and authentication of the meta connection is spread out over
meta.c and protocol_auth.c. The new protocol was added there as well,
leading to spaghetti code. To improve things, the new protocol will now
be implemented in sptps.[ch].

The goal is to have a very simplified version of TLS. There is a record
layer, and there are only two record types: application data and
handshake messages. The handshake message contains a random nonce, an
ephemeral ECDH public key, and an ECDSA signature over the former. After
the ECDH public keys are exchanged, a shared secret is calculated, and a
TLS style PRF is used to generate the key material for the cipher and
HMAC algorithm, and further communication is encrypted and authenticated.

A lot of the simplicity comes from the fact that both sides must have
each other's public keys in advance, and there are no options to choose.
There will be one fixed cipher suite, and both peers always authenticate
each other. (Inspiration taken from Ian Grigg's hypotheses[0].)
There might be some compromise in the future, to enable or disable
encryption, authentication and compression, but there will be no choice
of algorithms. This will allow SPTPS to be built with a few embedded
crypto algorithms instead of linking with huge crypto libraries.

The API is also kept simple. There is a start and a stop function. All
data necessary to make the connection work is passed in the start
function. Instead having both send- and receive-record functions, there
is a send-record function and a receive-data function. The latter will
pass protocol data received from the peer to the SPTPS implementation,
which will in turn call a receive-record callback function when
necessary. This hides all the handshaking from the application, and is
completely independent from any event loop or socket characteristics.

[0] http://iang.org/ssl/hn_hypotheses_in_secure_protocol_design.html
2011-07-24 15:44:51 +02:00