struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
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_size,
target_size);
if (target_size > 0)
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_size,
target_size);
int rc = 0;
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_size, 0);
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;
}
struct tls_rec *rec = ctx->open_rec;
int rc = 0;
- rc = sk_alloc_sg(sk, len, rec->sg_plaintext_data, 0,
- &rec->sg_plaintext_num_elem, &rec->sg_plaintext_size,
+ rc = sk_alloc_sg(sk, len,
+ &rec->sg_plaintext_data[1], 0,
+ &rec->sg_plaintext_num_elem,
+ &rec->sg_plaintext_size,
tls_ctx->pending_open_record_frags);
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;
}
if (!rec)
return;
- free_sg(sk, rec->sg_encrypted_data,
+ free_sg(sk, &rec->sg_encrypted_data[1],
&rec->sg_encrypted_num_elem,
&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_size);
* Remove the head of tx_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);
kfree(rec);
tx_flags = flags;
rc = tls_push_sg(sk, tls_ctx,
- &rec->sg_encrypted_data[0],
+ &rec->sg_encrypted_data[1],
0, tx_flags);
if (rc)
goto tx_err;
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 = container_of(aead_req, struct tls_rec, aead_req);
- rec->sg_encrypted_data[0].offset -= tls_ctx->tx.prepend_size;
- 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;
- /* Free the record if error is previously set on socket */
+ /* Check if error is previously set on socket */
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;
/* If err is already set on socket, return the same code */
/* Schedule the transmission */
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,
struct tls_rec *rec = ctx->open_rec;
int rc;
- rec->sg_encrypted_data[0].offset += tls_ctx->tx.prepend_size;
- rec->sg_encrypted_data[0].length -= tls_ctx->tx.prepend_size;
+ /* Skip the first index as it contains AAD data */
+ 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_ad(aead_req, TLS_AAD_SPACE_SIZE);
- aead_request_set_crypt(aead_req, rec->sg_aead_in,
- rec->sg_aead_out,
+ aead_request_set_crypt(aead_req, rec->sg_plaintext_data,
+ rec->sg_encrypted_data,
data_len, tls_ctx->tx.iv);
aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
rc = crypto_aead_encrypt(aead_req);
if (!rc || rc != -EINPROGRESS) {
atomic_dec(&ctx->encrypt_pending);
- rec->sg_encrypted_data[0].offset -= tls_ctx->tx.prepend_size;
- 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;
}
if (!rc) {
rec->tx_flags = flags;
req = &rec->aead_req;
- sg_mark_end(rec->sg_plaintext_data + rec->sg_plaintext_num_elem - 1);
- sg_mark_end(rec->sg_encrypted_data + rec->sg_encrypted_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);
tls_make_aad(rec->aad_space, rec->sg_plaintext_size,
tls_ctx->tx.rec_seq, tls_ctx->tx.rec_seq_size,
record_type);
tls_fill_prepend(tls_ctx,
- page_address(sg_page(&rec->sg_encrypted_data[0])) +
- rec->sg_encrypted_data[0].offset,
+ page_address(sg_page(&rec->sg_encrypted_data[1])) +
+ rec->sg_encrypted_data[1].offset,
rec->sg_plaintext_size, record_type);
tls_ctx->pending_open_record_frags = 0;
struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx);
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;
for (i = tls_ctx->pending_open_record_frags;
sg_init_table(&rec->sg_encrypted_data[0],
ARRAY_SIZE(rec->sg_encrypted_data));
- sg_init_table(rec->sg_aead_in, 2);
- sg_set_buf(&rec->sg_aead_in[0], rec->aad_space,
+ sg_set_buf(&rec->sg_plaintext_data[0], rec->aad_space,
sizeof(rec->aad_space));
- sg_unmark_end(&rec->sg_aead_in[1]);
- 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,
+ sg_set_buf(&rec->sg_encrypted_data[0], 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;
ret = zerocopy_from_iter(sk, &msg->msg_iter,
try_to_copy, &rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size,
- rec->sg_plaintext_data,
- ARRAY_SIZE(rec->sg_plaintext_data),
+ &rec->sg_plaintext_data[1],
+ ARRAY_SIZE(rec->sg_plaintext_data) - 1,
true);
if (ret)
goto fallback_to_reg_send;
continue;
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_size,
orig_size);
try_to_copy -= required_size - rec->sg_plaintext_size;
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_size,
rec->sg_plaintext_size +
}
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_unmark_end(sg);
if (full_record || eor ||
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);
if (ret) {
if (ret == -EINPROGRESS)
rec = list_first_entry(&ctx->tx_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_size);
}
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_size);
- free_sg(sk, rec->sg_plaintext_data,
+ free_sg(sk, &rec->sg_plaintext_data[1],
&rec->sg_plaintext_num_elem,
&rec->sg_plaintext_size);