Notes on SSL/TLS

ChaCha20, Poly1305, X25519

  • RFC7539 defines ChaCha20 and Poly1305
  • RFC7905 adds TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCA8) etc to TLS 1.2
  • There is an old version of ECDHE_RSA_CHACHA20_POLY1305_OLD (0xCC13) exists in draft and OpenSSL code.
  • OpenSSL will prefer AES if hardware supports it, otherwise prefer ChaCha20 over AES, in ssl_create_cipher_list().
  • Go 1.8 will support TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 commit 67d8226b48
commit 67d8226b4862f0f8deb4dc6fa8617017ecb0f32b
Author: Adam Langley <agl@golang.org>
Date:   Wed Oct 12 10:46:43 2016 -0700

    crypto/tls: support ChaCha20-Poly1305.

    This change adds support for the ChaCha20-Poly1305 AEAD to crypto/tls,
    as specified in https://tools.ietf.org/html/rfc7905.

    Fixes #15499.

    Change-Id: Iaa689be90e03f208c40b574eca399e56f3c7ecf1
    Reviewed-on: https://go-review.googlesource.com/30957
    Run-TryBot: Adam Langley <agl@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
commit 9e98e7e6686a500f87352e3721038d194b1db33c
Author: Adam Langley <agl@golang.org>
Date:   Tue Oct 11 15:08:35 2016 -0700

    crypto/tls: enable X25519 by default.

    Since this changes the offered curves in the ClientHello, all the test
    data needs to be updated too.

    Change-Id: I227934711104349c0f0eab11d854e5a2adcbc363
    Reviewed-on: https://go-review.googlesource.com/30825
    Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>

API changes

commit 320bd562cbb24a01beb02706c42d06a290160645
Author: Joonas Kuorilehto <joneskoo@derbian.fi>
Date:   Sat Aug 20 14:41:42 2016 +0300

    crypto/tls: add KeyLogWriter for debugging

    Add support for writing TLS client random and master secret
    in NSS key log format.

    https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format

    Normally this is enabled by a developer debugging TLS based
    applications, especially HTTP/2, by setting the KeyLogWriter
    to an open file. The keys negotiated in handshake are then
    logged and can be used to decrypt TLS sessions e.g. in Wireshark.

    Applications may choose to add support similar to NSS where this
    is enabled by environment variable, but no such mechanism is
    built in to Go. Instead each application must explicitly enable.

    Fixes #13057.

    Change-Id: If6edd2d58999903e8390b1674ba4257ecc747ae1
    Reviewed-on: https://go-review.googlesource.com/27434
    Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>

Memory footprint

  • Before OpenSSL 1.1.0, there is a free-list (~32k per SSL) unless disable with OPENSSL_NO_BUF_FREELISTS or set SSL_MODE_RELEASE_BUFFERS, the free list is freed in SSL_CTX_free() not SSL_free().

commit 63c574f6a6 in OpenSSL:

commit 63c574f6a639cfa3f53476080054526e6bfa3bc9
Author: Rich Salz <rsalz@openssl.org>
Date:   Tue Jan 27 16:43:53 2015 -0500

    OPENSSL_NO_XXX cleanup: OPENSSL_NO_BUF_FREELISTS

    Remove OPENSSL_NO_BUF_FREELISTS. This was turned on by default,
    so the work here is removing the 'maintain our own freelist' code.
    Also removed a minor old Windows-multibyte/widechar conversion flag.

commit 72e56bc494 in LibreSSL:

commit 72e56bc4947e53cec535f2fc84e00a3c278edf29
Author: tedu <>
Date:   Wed Apr 16 21:16:33 2014 +0000

    TANSTAAFL - delete the buf freelist code. if you need a better malloc, get
    a better malloc. ok beck deraadt

diff --git a/src/lib/libssl/s3_both.c b/src/lib/libssl/s3_both.c

TANSTAAFL - There ain't no such thing as a free lunch

commit 983f6bdb58 in BoringSSL:

commit 983f6bdb5888d7074d7ee67d5e3741bcf1027108
Author: Alex Chernyakhovsky <achernya@google.com>
Date:   Sun Aug 3 15:48:35 2014 -0400

    Set OPENSSL_NO_BUF_FREELISTS

    The memory freelist maintained by OpenSSL claims to be a performance
    optimization for platforms that have a slow malloc/free
    implementation. This should not be the case on modern
    linux/glibc. Remove the freelist as it poses a potential security
    hazard of buffer-reuse that is of "initialized" memory that will not
    be caught be tools such as valgrind.

    Change-Id: I3cfa6a05f9bdfbbba7820060bae5a673dee43014
    Reviewed-on: https://boringssl-review.googlesource.com/1385
    Reviewed-by: Adam Langley <agl@google.com>
  • After commit b8d28cf532 BoringSSL calls ssl_write_buffer_flush() and ssl_write_buffer_clear() for each SSL_write(), so its memory footprint is much smaller than other SSL libraries (~32k) when no data is pending.

Performance notes

The P-256 curve, also known as prime256v1 or secp256r1 is widely used in ECDHE_RSA key exchange.

For x86-64, there is a faster implementation, enabled by ./config enable-ec_nistp_64_gcc_128.

Futher speed up of P-256 in OpenSSL 1.1.0 and BoringSSL:

commit 18954938684e269ccd59152027d2244040e2b819
Author: Adam Langley <agl@google.com>
Date:   Tue Nov 3 14:02:04 2015 -0800

    Add Intel's P-256

    This change incorporates Intel's P-256 implementation. The record of
    Intel's submission under CLA is in internal bug number 25330687.

    Before:
    Did 3582 ECDH P-256 operations in 1049114us (3414.3 ops/sec)
    Did 8525 ECDSA P-256 signing operations in 1028778us (8286.5 ops/sec)
    Did 3487 ECDSA P-256 verify operations in 1008996us (3455.9 ops/sec)
    build/tool/bssl is 1434704 bytes after strip -s

    After:
    Did 8618 ECDH P-256 operations in 1027884us (8384.2 ops/sec)
    Did 21000 ECDSA P-256 signing operations in 1049490us (20009.7 ops/sec)
    Did 8268 ECDSA P-256 verify operations in 1079481us (7659.2 ops/sec)
    build/tool/bssl is 1567216 bytes after strip -s

    Change-Id: I147971a8e19849779c8ed7e20310d41bd4962299
    Reviewed-on: https://boringssl-review.googlesource.com/6371
    Reviewed-by: Adam Langley <agl@google.com>

None of them are available in LibreSSL as of Jan 19, 2017. Issue 259.

Cryptography