This library is an alteration of the OpenSSL Library. We changed the session resumption of TLS 1.3 such that any 0-RTT data is forward secret. More specifically, this library is the implementation of the ideas presented in 'Session Resumption Protocols and Efficient Forward Security for TLS 1.3 0-RTT' by Kai Gellert, Nimrod Aviram, and Tibor Jager.
This library is an alteration of the OpenSSL Library.
We changed the session resumption of TLS 1.3 such that any 0-RTT data is
forward secret. More specifically, this library is the implementation of
the ideas presented in 'Session Resumption Protocols and Efficient Forward
Security for TLS 1.3 0-RTT' by Kai Gellert, Nimrod Aviram, and Tibor Jager.
In a usual OpenSSL session resumption the server sends a ticket to the client which is encrypted with a static key. Should this static key be leaked at a later point in time an adversary could decrypt every ticket. Knowing the contents of the ticket, an adversary could also decrypt any 0-RTT data. To make this process forward secret, the servers needs a changing key which is able to decrypt all old session tickets but never able to decrypt any session ticket twice. The solution presented by Gellert, Aviram, and Jager were puncturable pseudo-random functions (PPRFs). Once a ticket has been evaluated once with the PPRF, the PPRF can be punctured to make a second evaluation impossible. We refer to 'Session Resumption Protocols and Efficient Forward Security for TLS 1.3 0-RTT' for more details of the PPRFs and Forward Secret Session Resumption.
In a usual OpenSSL session resumption the server sends a ticket to the
client which is encrypted with a static key. Should this static key be
leaked at a later point in time an adversary could decrypt every ticket.
Knowing the contents of the ticket, an adversary could also decrypt any
0-RTT data. To make this process forward secret, the servers needs a
changing key which is able to decrypt all old session tickets but never
able to decrypt any session ticket twice. The solution presented by Gellert,
Aviram, and Jager were puncturable pseudo-random functions (PPRFs). Once a
ticket has been evaluated once with the PPRF, the PPRF can be punctured to
make a second evaluation impossible. We refer to 'Session Resumption Protocols
and Efficient Forward Security for TLS 1.3 0-RTT' for more details of the
To use a changing key and the PPRF for ticket encryption instead of a static key the ticket encryption and decryption process of OpenSSL had to be changed. The new process is as follows:
To use a changing key and the PPRF for ticket encryption instead of a static
key the ticket encryption and decryption process of OpenSSL had to be changed.
The new process is as follows:
1. Get current ticket number n (from an increasing counter or the client)
2. Encrypt/Decrypt n with static key
...
...
@@ -20,43 +37,79 @@ To use a changing key and the PPRF for ticket encryption instead of a static key
4. Encrypt/Decrypt session ticket with k
5. Puncture PPRF on n (only after decryption)
By construction of the PPRFs the key k will be the same for n regardless of any punctures of the PPRF on any other value n'.
By construction of the PPRFs the key k will be the same for n regardless of
any punctures of the PPRF on any other value n'.
Any ticket has the follwing form
key_name || n_iv || iv || n_enc || enc
key_name is a key_name unique to a server. This way session ticket will never be valid for other servers. The n_iv is the initialization vector for the encryption of the counter n. The iv is the initialization vector of the encryption of the session ticket. n_enc and enc are the encryptions of n and the session ticket respectively. The encryption of n with a static key is, of course, not forward secret and serves the purpose of hiding information of the amount of connections that the server has.
key_name is a key_name unique to a server. This way session ticket will never
be valid for other servers. The n_iv is the initialization vector for the
encryption of the counter n. The iv is the initialization vector of the
encryption of the session ticket. n_enc and enc are the encryptions of n and
the session ticket respectively. The encryption of n with a static key is, of
course, not forward secret and serves the purpose of hiding information of the
The code for the two supported PPRFs lies in openssl_pprf/crypto/pprf. The punctpprf.c file contains all the functions of an interface that can use either of the two functions. The functions are also declared in openssl_pprf/include/pprf.h. Which PPRF should be used can be defined in the punctpprf.c file. The two PPRFs can be changed in the openssl_pprf/crypto/pprf folder and should require no additional changes in the rest of the library as long as the headers stay the same.
The code for the two supported PPRFs lies in openssl_pprf/crypto/pprf.
The punctpprf.c file contains all the functions of an interface that can
use either of the two functions. The functions are also declared in
openssl_pprf/include/pprf.h. Which PPRF should be used can be defined in
the punctpprf.c file. The two PPRFs can be changed in the
openssl_pprf/crypto/pprf folder and should require no additional changes
in the rest of the library as long as the headers stay the same.
2. Setup and tear-down
The PPRF is initialized and cleaned together with other parts of the OpenSSL library in openssl_pprf/ssl/ssl_lib.c. The setup is done in line 3141 and the clean-up is done in line 3309. Additionally, the SSL_CTX_ECT_SECURE struct had to be changed to contain information about the PPRF. This happens in line 737 in openssl_pprf/ssl/ssl_locl.h
The PPRF is initialized and cleaned together with other parts of the OpenSSL
library in openssl_pprf/ssl/ssl_lib.c. The setup is done in line 3141 and the
clean-up is done in line 3309. Additionally, the SSL_CTX_ECT_SECURE struct had
to be changed to contain information about the PPRF. This happens in line 737
in openssl_pprf/ssl/ssl_locl.h
3. Ticket encryption
OpenSSL encrypts TLS 1.3 tickets in openssl_pprf/statem/statem_server.c. We changed the construct_stateless_ticket method following line 3834. The server gets the current ticket number n and evaluates the PPRF on n to receive k. The server then encrypts n with a static key and the session ticket with key k. The encryption of both n and k are part of the session ticket.
OpenSSL encrypts TLS 1.3 tickets in openssl_pprf/statem/statem_server.c.
We changed the construct_stateless_ticket method following line 3834.
The server gets the current ticket number n and evaluates the PPRF on n to
receive k. The server then encrypts n with a static key and the session ticket
with key k. The encryption of both n and k are part of the session ticket.
4. Ticket decryption
OpenSSL decrypts TLS 1.3 tickets in openssl_pprf/ssl/t1_lib.c. We changed the tls_decrypt_ticket method following line 1402. The server must decrypt n_enc with its static key and n_iv to receive n. It uses that n to receive the key k from the used PPRF by evaluating the PPRF on n. The server uses k to decrypt enc using iv. This decryption will be the final session ticket. As a final operation, the server punctures the PPRF on value n, so the key k can never be received from it anymore.
We hope that the comment in the changed methods together with the research paper mentioned above are sufficient to understand what is happening in the library. OpenSSL itself is not commented to a large extend which might make a proper understanding arduous.
OpenSSL decrypts TLS 1.3 tickets in openssl_pprf/ssl/t1_lib.c. We changed the
tls_decrypt_ticket method following line 1402. The server must decrypt n_enc
with its static key and n_iv to receive n. It uses that n to receive the key k
from the used PPRF by evaluating the PPRF on n. The server uses k to decrypt
enc using iv. This decryption will be the final session ticket. As a final
operation, the server punctures the PPRF on value n, so the key k can never
be received from it anymore.
We hope that the comment in the changed methods together with the research
paper mentioned above are sufficient to understand what is happening in the
library. OpenSSL itself is not commented to a large extend which might make
We provide a Dockerfile that is able to compile our altered version of OpenSSL into a Docker container. The server can be compiled using make build. The server can be run with make run. To test the ticket creation and decryption run
We provide a Dockerfile that is able to compile our altered version of OpenSSL
into a Docker container. The server can be compiled using make build. The
server can be run with make run. To test the ticket creation and decryption run
This will start a sample client that connects to the started server and tests the session resumption. The client will indicate a re-used TLS 1.3 session on the second command.
This will start a sample client that connects to the started server and tests
the session resumption. The client will indicate a re-used TLS 1.3 session on
the second command.
Additionally, we provide possibilities to test the PPRFs without OpenSSL in the PPRFs (offline testing) folder.
Additionally, we provide possibilities to test the PPRFs without OpenSSL in the
PPRFs (offline testing) folder.
Please write an e-mail to nniklas@mail.uni-paderborn.de for any questions.