#
# You may specify multiple input ports; save for TLS settings (TLS is automatically
# enabled for a port if you give a key pair), they are treated exactly the same.
-# “port N” is equivalent to “listen [::]:N”. TLS requires kTLS support (Linux >= 4.13,
-# CONFIG_TLS enabled).
+# “port N” is equivalent to “listen [::]:N”. TLS requires kTLS support with both
+# RX and TX (Linux >= 4.17, CONFIG_TLS enabled).
#
port 9094
# listen 127.0.0.1:9095
{
switch (client->state) {
case Client::READING_REQUEST: {
- if (client->tls_context != nullptr) {
+ if (client->tls_context != nullptr && !client->in_ktls_mode) {
if (send_pending_tls_data(client)) {
// send_pending_tls_data() hit postconditions #1 or #4.
return;
// Try to read more of the request.
char buf[1024];
int ret;
- if (client->tls_context == nullptr) {
- ret = read_nontls_data(client, buf, sizeof(buf));
+ if (client->tls_context == nullptr || client->in_ktls_mode) {
+ ret = read_plain_data(client, buf, sizeof(buf));
if (ret == -1) {
- // read_nontls_data() hit postconditions #1 or #2.
+ // read_plain_data() hit postconditions #1 or #2.
return;
}
} else {
assert(status == RP_FINISHED);
- if (client->tls_context && !client->in_ktls_mode && tls_established(client->tls_context)) {
- // We're ready to enter kTLS mode, unless we still have some
- // handshake data to send (which then must be sent as non-kTLS).
- if (send_pending_tls_data(client)) {
- // send_pending_tls_data() hit postconditions #1 or #4.
- return;
- }
- ret = tls_make_ktls(client->tls_context, client->sock);
- if (ret < 0) {
- log_tls_error("tls_make_ktls", ret);
- close_client(client);
- return;
- }
- client->in_ktls_mode = true;
- }
-
int error_code = parse_request(client);
if (error_code == 200) {
if (client->serving_hls_playlist) {
goto send_data_again;
}
-int Server::read_nontls_data(Client *client, char *buf, size_t max_size)
+int Server::read_plain_data(Client *client, char *buf, size_t max_size)
{
int ret;
do {
int Server::read_tls_data(Client *client, char *buf, size_t max_size)
{
read_again:
+ assert(!client->in_ktls_mode);
+
int ret;
do {
ret = read(client->sock, buf, max_size);
return -1;
}
+ if (tls_established(client->tls_context)) {
+ // We're ready to enter kTLS mode, unless we still have some
+ // handshake data to send (which then must be sent as non-kTLS).
+ if (send_pending_tls_data(client)) {
+ // send_pending_tls_data() hit postconditions #1 or #4.
+ return -1;
+ }
+ int err = tls_make_ktls(client->tls_context, client->sock); // Don't overwrite ret.
+ if (err < 0) {
+ log_tls_error("tls_make_ktls", ret);
+ close_client(client);
+ return -1;
+ }
+ client->in_ktls_mode = true;
+ }
+
assert(ret > 0);
return ret;
}
// Reads regular data fro ma socket. Returns -1 if the processing
// should go to sleep (an error, or no data available yet), otherwise
// the number of bytes read.
- int read_nontls_data(Client *client, char *buf, size_t max_size);
+ int read_plain_data(Client *client, char *buf, size_t max_size);
// Reads (decrypted) data from a TLS socket. Returns -1 if the processing
// should go to sleep (an error, or no data available yet), otherwise
/* TLS socket options */
#define TLS_TX 1 /* Set transmit parameters */
+#define TLS_RX 2 /* Set receive parameters */
/* Supported versions */
#define TLS_VERSION_MINOR(ver) ((ver) & 0xFF)
}\r
memcpy(crypto_info.rec_seq, &context->local_sequence_number, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);\r
context->local_sequence_number = ntohll(context->local_sequence_number);\r
+#ifdef TLS_RX\r
+ crypt_info_size = sizeof(crypto_info);\r
+ if (getsockopt(socket, SOL_TLS, TLS_RX, &crypto_info, &crypt_info_size)) {\r
+ DEBUG_PRINT("ERROR IN getsockopt\n");\r
+ return TLS_GENERIC_ERROR;\r
+ }\r
+ memcpy(crypto_info.rec_seq, &context->remote_sequence_number, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);\r
+ context->remote_sequence_number = ntohll(context->remote_sequence_number);\r
+#endif\r
return 0;\r
#endif\r
DEBUG_PRINT("TLSe COMPILED WITHOUT kTLS SUPPORT\n");\r
return TLS_FEATURE_NOT_SUPPORTED;\r
}\r
#ifdef WITH_KTLS\r
- if (context->exportable_size < TLS_CIPHER_AES_GCM_128_KEY_SIZE) {\r
+ if (context->exportable_size < TLS_CIPHER_AES_GCM_128_KEY_SIZE * 2) {\r
DEBUG_PRINT("INVALID KEY SIZE\n");\r
return TLS_GENERIC_ERROR;\r
}\r
memcpy(crypto_info.rec_seq, &local_sequence_number, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);\r
memcpy(crypto_info.key, context->exportable_keys, TLS_CIPHER_AES_GCM_128_KEY_SIZE);\r
memcpy(crypto_info.salt, context->crypto.ctx_local_mac.local_aead_iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);\r
+\r
setsockopt(socket, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));\r
+\r
+#ifdef TLS_RX\r
+ // kernel 4.17 adds TLS_RX support\r
+ struct tls12_crypto_info_aes_gcm_128 crypto_info_read;\r
+\r
+ crypto_info_read.info.version = TLS_1_2_VERSION;\r
+ crypto_info_read.info.cipher_type = TLS_CIPHER_AES_GCM_128;\r
+\r
+ uint64_t remote_sequence_number = htonll(context->remote_sequence_number);\r
+ memcpy(crypto_info_read.iv, &remote_sequence_number, TLS_CIPHER_AES_GCM_128_IV_SIZE);\r
+ memcpy(crypto_info_read.rec_seq, &remote_sequence_number, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);\r
+ memcpy(crypto_info_read.key, context->exportable_keys + TLS_CIPHER_AES_GCM_128_KEY_SIZE, TLS_CIPHER_AES_GCM_128_KEY_SIZE);\r
+ memcpy(crypto_info_read.salt, context->crypto.ctx_remote_mac.remote_aead_iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);\r
+\r
+ int err = setsockopt(socket, SOL_TLS, TLS_RX, &crypto_info_read, sizeof(crypto_info_read));\r
+ if (err)\r
+ return err;\r
+#endif\r
return setsockopt(socket, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info));\r
#else\r
DEBUG_PRINT("TLSe COMPILED WITHOUT kTLS SUPPORT\n");\r