1
0
Fork 0

tls: Remove redundant vars from tls record structure

Structure 'tls_rec' contains sg_aead_in and sg_aead_out which point
to a aad_space and then chain scatterlists sg_plaintext_data,
sg_encrypted_data respectively. Rather than using chained scatterlists
for plaintext and encrypted data in aead_req, it is efficient to store
aad_space in sg_encrypted_data and sg_plaintext_data itself in the
first index and get rid of sg_aead_in, sg_aead_in and further chaining.

This requires increasing size of sg_encrypted_data & sg_plaintext_data
arrarys by 1 to accommodate entry for aad_space. The code which uses
sg_encrypted_data and sg_plaintext_data has been modified to skip first
index as it points to aad_space.

Signed-off-by: Vakul Garg <vakul.garg@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
hifive-unleashed-5.1
Vakul Garg 2018-09-26 16:22:08 +05:30 committed by David S. Miller
parent 6e9feb3391
commit 80ece6a03a
2 changed files with 45 additions and 53 deletions

View File

@ -101,13 +101,11 @@ struct tls_rec {
struct list_head list; struct list_head list;
int tx_ready; int tx_ready;
int tx_flags; int tx_flags;
struct scatterlist sg_plaintext_data[MAX_SKB_FRAGS];
struct scatterlist sg_encrypted_data[MAX_SKB_FRAGS];
/* AAD | sg_plaintext_data | sg_tag */ /* AAD | sg_plaintext_data | sg_tag */
struct scatterlist sg_aead_in[2]; struct scatterlist sg_plaintext_data[MAX_SKB_FRAGS + 1];
/* AAD | sg_encrypted_data (data contain overhead for hdr&iv&tag) */ /* AAD | sg_encrypted_data (data contain overhead for hdr&iv&tag) */
struct scatterlist sg_aead_out[2]; struct scatterlist sg_encrypted_data[MAX_SKB_FRAGS + 1];
unsigned int sg_plaintext_size; unsigned int sg_plaintext_size;
unsigned int sg_encrypted_size; unsigned int sg_encrypted_size;

View File

@ -248,7 +248,7 @@ static void trim_both_sgl(struct sock *sk, int target_size)
struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
struct tls_rec *rec = ctx->open_rec; struct tls_rec *rec = ctx->open_rec;
trim_sg(sk, rec->sg_plaintext_data, trim_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size, &rec->sg_plaintext_size,
target_size); target_size);
@ -256,7 +256,7 @@ static void trim_both_sgl(struct sock *sk, int target_size)
if (target_size > 0) if (target_size > 0)
target_size += tls_ctx->tx.overhead_size; target_size += tls_ctx->tx.overhead_size;
trim_sg(sk, rec->sg_encrypted_data, trim_sg(sk, &rec->sg_encrypted_data[1],
&rec->sg_encrypted_num_elem, &rec->sg_encrypted_num_elem,
&rec->sg_encrypted_size, &rec->sg_encrypted_size,
target_size); target_size);
@ -270,12 +270,13 @@ static int alloc_encrypted_sg(struct sock *sk, int len)
int rc = 0; int rc = 0;
rc = sk_alloc_sg(sk, len, rc = sk_alloc_sg(sk, len,
rec->sg_encrypted_data, 0, &rec->sg_encrypted_data[1], 0,
&rec->sg_encrypted_num_elem, &rec->sg_encrypted_num_elem,
&rec->sg_encrypted_size, 0); &rec->sg_encrypted_size, 0);
if (rc == -ENOSPC) if (rc == -ENOSPC)
rec->sg_encrypted_num_elem = ARRAY_SIZE(rec->sg_encrypted_data); rec->sg_encrypted_num_elem =
ARRAY_SIZE(rec->sg_encrypted_data) - 1;
return rc; return rc;
} }
@ -287,12 +288,15 @@ static int alloc_plaintext_sg(struct sock *sk, int len)
struct tls_rec *rec = ctx->open_rec; struct tls_rec *rec = ctx->open_rec;
int rc = 0; int rc = 0;
rc = sk_alloc_sg(sk, len, rec->sg_plaintext_data, 0, rc = sk_alloc_sg(sk, len,
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_size, &rec->sg_plaintext_data[1], 0,
&rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size,
tls_ctx->pending_open_record_frags); tls_ctx->pending_open_record_frags);
if (rc == -ENOSPC) if (rc == -ENOSPC)
rec->sg_plaintext_num_elem = ARRAY_SIZE(rec->sg_plaintext_data); rec->sg_plaintext_num_elem =
ARRAY_SIZE(rec->sg_plaintext_data) - 1;
return rc; return rc;
} }
@ -320,11 +324,11 @@ static void tls_free_open_rec(struct sock *sk)
if (!rec) if (!rec)
return; return;
free_sg(sk, rec->sg_encrypted_data, free_sg(sk, &rec->sg_encrypted_data[1],
&rec->sg_encrypted_num_elem, &rec->sg_encrypted_num_elem,
&rec->sg_encrypted_size); &rec->sg_encrypted_size);
free_sg(sk, rec->sg_plaintext_data, free_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size); &rec->sg_plaintext_size);
@ -355,7 +359,7 @@ int tls_tx_records(struct sock *sk, int flags)
* Remove the head of tx_list * Remove the head of tx_list
*/ */
list_del(&rec->list); list_del(&rec->list);
free_sg(sk, rec->sg_plaintext_data, free_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_size); &rec->sg_plaintext_num_elem, &rec->sg_plaintext_size);
kfree(rec); kfree(rec);
@ -370,13 +374,13 @@ int tls_tx_records(struct sock *sk, int flags)
tx_flags = flags; tx_flags = flags;
rc = tls_push_sg(sk, tls_ctx, rc = tls_push_sg(sk, tls_ctx,
&rec->sg_encrypted_data[0], &rec->sg_encrypted_data[1],
0, tx_flags); 0, tx_flags);
if (rc) if (rc)
goto tx_err; goto tx_err;
list_del(&rec->list); list_del(&rec->list);
free_sg(sk, rec->sg_plaintext_data, free_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size); &rec->sg_plaintext_size);
@ -405,16 +409,12 @@ static void tls_encrypt_done(struct crypto_async_request *req, int err)
rec = container_of(aead_req, struct tls_rec, aead_req); rec = container_of(aead_req, struct tls_rec, aead_req);
rec->sg_encrypted_data[0].offset -= tls_ctx->tx.prepend_size; rec->sg_encrypted_data[1].offset -= tls_ctx->tx.prepend_size;
rec->sg_encrypted_data[0].length += tls_ctx->tx.prepend_size; rec->sg_encrypted_data[1].length += tls_ctx->tx.prepend_size;
/* Free the record if error is previously set on socket */ /* Check if error is previously set on socket */
if (err || sk->sk_err) { if (err || sk->sk_err) {
free_sg(sk, rec->sg_encrypted_data,
&rec->sg_encrypted_num_elem, &rec->sg_encrypted_size);
kfree(rec);
rec = NULL; rec = NULL;
/* If err is already set on socket, return the same code */ /* If err is already set on socket, return the same code */
@ -449,7 +449,7 @@ static void tls_encrypt_done(struct crypto_async_request *req, int err)
/* Schedule the transmission */ /* Schedule the transmission */
if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
schedule_delayed_work(&ctx->tx_work.work, 1); schedule_delayed_work(&ctx->tx_work.work, 2);
} }
static int tls_do_encryption(struct sock *sk, static int tls_do_encryption(struct sock *sk,
@ -461,13 +461,14 @@ static int tls_do_encryption(struct sock *sk,
struct tls_rec *rec = ctx->open_rec; struct tls_rec *rec = ctx->open_rec;
int rc; int rc;
rec->sg_encrypted_data[0].offset += tls_ctx->tx.prepend_size; /* Skip the first index as it contains AAD data */
rec->sg_encrypted_data[0].length -= tls_ctx->tx.prepend_size; rec->sg_encrypted_data[1].offset += tls_ctx->tx.prepend_size;
rec->sg_encrypted_data[1].length -= tls_ctx->tx.prepend_size;
aead_request_set_tfm(aead_req, ctx->aead_send); aead_request_set_tfm(aead_req, ctx->aead_send);
aead_request_set_ad(aead_req, TLS_AAD_SPACE_SIZE); aead_request_set_ad(aead_req, TLS_AAD_SPACE_SIZE);
aead_request_set_crypt(aead_req, rec->sg_aead_in, aead_request_set_crypt(aead_req, rec->sg_plaintext_data,
rec->sg_aead_out, rec->sg_encrypted_data,
data_len, tls_ctx->tx.iv); data_len, tls_ctx->tx.iv);
aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
@ -480,8 +481,8 @@ static int tls_do_encryption(struct sock *sk,
rc = crypto_aead_encrypt(aead_req); rc = crypto_aead_encrypt(aead_req);
if (!rc || rc != -EINPROGRESS) { if (!rc || rc != -EINPROGRESS) {
atomic_dec(&ctx->encrypt_pending); atomic_dec(&ctx->encrypt_pending);
rec->sg_encrypted_data[0].offset -= tls_ctx->tx.prepend_size; rec->sg_encrypted_data[1].offset -= tls_ctx->tx.prepend_size;
rec->sg_encrypted_data[0].length += tls_ctx->tx.prepend_size; rec->sg_encrypted_data[1].length += tls_ctx->tx.prepend_size;
} }
if (!rc) { if (!rc) {
@ -512,16 +513,16 @@ static int tls_push_record(struct sock *sk, int flags,
rec->tx_flags = flags; rec->tx_flags = flags;
req = &rec->aead_req; req = &rec->aead_req;
sg_mark_end(rec->sg_plaintext_data + rec->sg_plaintext_num_elem - 1); sg_mark_end(rec->sg_plaintext_data + rec->sg_plaintext_num_elem);
sg_mark_end(rec->sg_encrypted_data + rec->sg_encrypted_num_elem - 1); sg_mark_end(rec->sg_encrypted_data + rec->sg_encrypted_num_elem);
tls_make_aad(rec->aad_space, rec->sg_plaintext_size, tls_make_aad(rec->aad_space, rec->sg_plaintext_size,
tls_ctx->tx.rec_seq, tls_ctx->tx.rec_seq_size, tls_ctx->tx.rec_seq, tls_ctx->tx.rec_seq_size,
record_type); record_type);
tls_fill_prepend(tls_ctx, tls_fill_prepend(tls_ctx,
page_address(sg_page(&rec->sg_encrypted_data[0])) + page_address(sg_page(&rec->sg_encrypted_data[1])) +
rec->sg_encrypted_data[0].offset, rec->sg_encrypted_data[1].offset,
rec->sg_plaintext_size, record_type); rec->sg_plaintext_size, record_type);
tls_ctx->pending_open_record_frags = 0; tls_ctx->pending_open_record_frags = 0;
@ -613,7 +614,7 @@ static int memcopy_from_iter(struct sock *sk, struct iov_iter *from,
struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
struct tls_rec *rec = ctx->open_rec; struct tls_rec *rec = ctx->open_rec;
struct scatterlist *sg = rec->sg_plaintext_data; struct scatterlist *sg = &rec->sg_plaintext_data[1];
int copy, i, rc = 0; int copy, i, rc = 0;
for (i = tls_ctx->pending_open_record_frags; for (i = tls_ctx->pending_open_record_frags;
@ -659,17 +660,10 @@ static struct tls_rec *get_rec(struct sock *sk)
sg_init_table(&rec->sg_encrypted_data[0], sg_init_table(&rec->sg_encrypted_data[0],
ARRAY_SIZE(rec->sg_encrypted_data)); ARRAY_SIZE(rec->sg_encrypted_data));
sg_init_table(rec->sg_aead_in, 2); sg_set_buf(&rec->sg_plaintext_data[0], rec->aad_space,
sg_set_buf(&rec->sg_aead_in[0], rec->aad_space,
sizeof(rec->aad_space)); sizeof(rec->aad_space));
sg_unmark_end(&rec->sg_aead_in[1]); sg_set_buf(&rec->sg_encrypted_data[0], rec->aad_space,
sg_chain(rec->sg_aead_in, 2, rec->sg_plaintext_data);
sg_init_table(rec->sg_aead_out, 2);
sg_set_buf(&rec->sg_aead_out[0], rec->aad_space,
sizeof(rec->aad_space)); sizeof(rec->aad_space));
sg_unmark_end(&rec->sg_aead_out[1]);
sg_chain(rec->sg_aead_out, 2, rec->sg_encrypted_data);
ctx->open_rec = rec; ctx->open_rec = rec;
@ -763,8 +757,8 @@ alloc_encrypted:
ret = zerocopy_from_iter(sk, &msg->msg_iter, ret = zerocopy_from_iter(sk, &msg->msg_iter,
try_to_copy, &rec->sg_plaintext_num_elem, try_to_copy, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size, &rec->sg_plaintext_size,
rec->sg_plaintext_data, &rec->sg_plaintext_data[1],
ARRAY_SIZE(rec->sg_plaintext_data), ARRAY_SIZE(rec->sg_plaintext_data) - 1,
true); true);
if (ret) if (ret)
goto fallback_to_reg_send; goto fallback_to_reg_send;
@ -781,7 +775,7 @@ alloc_encrypted:
continue; continue;
fallback_to_reg_send: fallback_to_reg_send:
trim_sg(sk, rec->sg_plaintext_data, trim_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size, &rec->sg_plaintext_size,
orig_size); orig_size);
@ -801,7 +795,7 @@ alloc_plaintext:
try_to_copy -= required_size - rec->sg_plaintext_size; try_to_copy -= required_size - rec->sg_plaintext_size;
full_record = true; full_record = true;
trim_sg(sk, rec->sg_encrypted_data, trim_sg(sk, &rec->sg_encrypted_data[1],
&rec->sg_encrypted_num_elem, &rec->sg_encrypted_num_elem,
&rec->sg_encrypted_size, &rec->sg_encrypted_size,
rec->sg_plaintext_size + rec->sg_plaintext_size +
@ -949,7 +943,7 @@ alloc_payload:
} }
get_page(page); get_page(page);
sg = rec->sg_plaintext_data + rec->sg_plaintext_num_elem; sg = &rec->sg_plaintext_data[1] + rec->sg_plaintext_num_elem;
sg_set_page(sg, page, copy, offset); sg_set_page(sg, page, copy, offset);
sg_unmark_end(sg); sg_unmark_end(sg);
@ -963,7 +957,7 @@ alloc_payload:
if (full_record || eor || if (full_record || eor ||
rec->sg_plaintext_num_elem == rec->sg_plaintext_num_elem ==
ARRAY_SIZE(rec->sg_plaintext_data)) { ARRAY_SIZE(rec->sg_plaintext_data) - 1) {
ret = tls_push_record(sk, flags, record_type); ret = tls_push_record(sk, flags, record_type);
if (ret) { if (ret) {
if (ret == -EINPROGRESS) if (ret == -EINPROGRESS)
@ -1571,7 +1565,7 @@ void tls_sw_free_resources_tx(struct sock *sk)
rec = list_first_entry(&ctx->tx_list, rec = list_first_entry(&ctx->tx_list,
struct tls_rec, list); struct tls_rec, list);
free_sg(sk, rec->sg_plaintext_data, free_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size); &rec->sg_plaintext_size);
@ -1580,11 +1574,11 @@ void tls_sw_free_resources_tx(struct sock *sk)
} }
list_for_each_entry_safe(rec, tmp, &ctx->tx_list, list) { list_for_each_entry_safe(rec, tmp, &ctx->tx_list, list) {
free_sg(sk, rec->sg_encrypted_data, free_sg(sk, &rec->sg_encrypted_data[1],
&rec->sg_encrypted_num_elem, &rec->sg_encrypted_num_elem,
&rec->sg_encrypted_size); &rec->sg_encrypted_size);
free_sg(sk, rec->sg_plaintext_data, free_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size); &rec->sg_plaintext_size);