What is the lightweight key exchange protocol of choice? Assume I have to implement a secure channel protocol by myself. Assume further that for some obscure reasons (library restrictions?) I can't use any of the pre-made libraries for SSH, TLS and such. Assume even further that there are only few algorithms available namely the neccessary ones, such as AES, GCM, ECDH, ECDSA and SHA-256. And of course I'd like to avoid patent issues if anyhow possible.

Now I know that it's hard to implement TLS right, as can be observed at those many vulnerabilities on the common libraries (LibreSSL, OpenSSL,...). And I strongly suspect the same to be true for SSH and IPSec (=IKEv2).

Let's ignore the record layer (in TLS terms) of the secure channel and focus on the key exchange - for this question.

What is the simplest key exchange protocol with proven security against as many as possible attacks?

What the protocol should do is clear: Do some operations and as few as possible message exchanges and output a strong random shared secret at the end that may only be known by the two authenticated parties. This common shared secret should (of course) enjoy the forward secrecy property and it may not be completely chosen by one party.

The complexity requirements are also clear: The protocol should be a lot simpler than TLS with its myriad of extensions and it shouldn't be much more computationally intense than TLS either.

As far as the research goes, I know about STS suiting most security notions but also being vulnerable to some attacks. I know that there is MQV but it also had issues and seems to be covered by patents.
I would personally use triple Diffie-Hellman, which is used often in secure instant-messaging protocols but unfortunately not very well-known beyond that. Essentially, both parties have a long-term identity DH keypair, which they must securely share beforehand (through some CA system, manual fingerprint confirmation like SSH, etc). In each session, both parties also generate an ephemeral DH keypair.

Both parties send their identity and ephemeral public keys to each other, and do this:

DH1 = DH(their_identity_public_key, our_ephemeral_private_key)
DH2 = DH(their_ephemeral_public_key, our_identity_private_key)
DH3 = DH(their_ephemeral_public_key, our_ephemeral_private_key)
SK = KDF(DH1 || DH2 || DH3)


This derives a shared secret that they can use with symmetric encryption etc like TLS (don't forget to derive different keys for the two directions, and to use authenticated encryption!)

Triple DH provides both security and authentication against active attackers, as long as both parties know (a hash of) the other's identity public key beforehand. It also has the following desirable properties:


Forward secrecy: the ephemeral keypairs are thrown away after the session is done, so even stealing the long-term keypairs in the future cannot compromise recorded past sessions
Simplicity: the scheme's security relies entirely on that of one primitive: Diffie-Hellman, and by simply plugging in different functions for DH you can use variants like X25519, NIST-standardized ECDHE, classical DH, etc. There is also no need to maintain multiple keys; only the identity key needs to be kept around and kept secret.
Deniability: this is a property that most protocols do not have: although the key exchange is authenticated to the two parties, after it happens the two ends cannot present cryptographic proof that the session ever happened, since both parties can forge a convincing transcript of messages. (For a non-deniable protocol, see ECDSA-signed ECDHE, very commonly in used in TLS. It uses Diffie-Hellman and has forward secrecy, but signing the key-exchange messages with an ECDSA key destroys deniability)