Skip to content

Commit b89fec5

Browse files
committed
tls: rx: wrap decrypt params in a struct
The max size of iv + aad + tail is 22B. That's smaller than a single sg entry (32B). Don't bother with the memory packing, just create a struct which holds the max size of those members. Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 50a07aa commit b89fec5

File tree

1 file changed

+30
-30
lines changed

1 file changed

+30
-30
lines changed

net/tls/tls_sw.c

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ struct tls_decrypt_arg {
5050
u8 tail;
5151
};
5252

53+
struct tls_decrypt_ctx {
54+
u8 iv[MAX_IV_SIZE];
55+
u8 aad[TLS_MAX_AAD_SIZE];
56+
u8 tail;
57+
struct scatterlist sg[];
58+
};
59+
5360
noinline void tls_err_abort(struct sock *sk, int err)
5461
{
5562
WARN_ON_ONCE(err >= 0);
@@ -1414,17 +1421,18 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
14141421
struct tls_context *tls_ctx = tls_get_ctx(sk);
14151422
struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
14161423
struct tls_prot_info *prot = &tls_ctx->prot_info;
1424+
int n_sgin, n_sgout, aead_size, err, pages = 0;
14171425
struct strp_msg *rxm = strp_msg(skb);
14181426
struct tls_msg *tlm = tls_msg(skb);
1419-
int n_sgin, n_sgout, nsg, mem_size, aead_size, err, pages = 0;
1420-
u8 *aad, *iv, *tail, *mem = NULL;
14211427
struct aead_request *aead_req;
14221428
struct sk_buff *unused;
14231429
struct scatterlist *sgin = NULL;
14241430
struct scatterlist *sgout = NULL;
14251431
const int data_len = rxm->full_len - prot->overhead_size;
14261432
int tail_pages = !!prot->tail_size;
1433+
struct tls_decrypt_ctx *dctx;
14271434
int iv_offset = 0;
1435+
u8 *mem;
14281436

14291437
if (darg->zc && (out_iov || out_sg)) {
14301438
if (out_iov)
@@ -1446,67 +1454,59 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
14461454
/* Increment to accommodate AAD */
14471455
n_sgin = n_sgin + 1;
14481456

1449-
nsg = n_sgin + n_sgout;
1450-
1451-
aead_size = sizeof(*aead_req) + crypto_aead_reqsize(ctx->aead_recv);
1452-
mem_size = aead_size + (nsg * sizeof(struct scatterlist));
1453-
mem_size = mem_size + TLS_MAX_AAD_SIZE;
1454-
mem_size = mem_size + MAX_IV_SIZE;
1455-
mem_size = mem_size + prot->tail_size;
1456-
14571457
/* Allocate a single block of memory which contains
1458-
* aead_req || sgin[] || sgout[] || aad || iv || tail.
1459-
* This order achieves correct alignment for aead_req, sgin, sgout.
1458+
* aead_req || tls_decrypt_ctx.
1459+
* Both structs are variable length.
14601460
*/
1461-
mem = kmalloc(mem_size, sk->sk_allocation);
1461+
aead_size = sizeof(*aead_req) + crypto_aead_reqsize(ctx->aead_recv);
1462+
mem = kmalloc(aead_size + struct_size(dctx, sg, n_sgin + n_sgout),
1463+
sk->sk_allocation);
14621464
if (!mem)
14631465
return -ENOMEM;
14641466

14651467
/* Segment the allocated memory */
14661468
aead_req = (struct aead_request *)mem;
1467-
sgin = (struct scatterlist *)(mem + aead_size);
1468-
sgout = sgin + n_sgin;
1469-
aad = (u8 *)(sgout + n_sgout);
1470-
iv = aad + TLS_MAX_AAD_SIZE;
1471-
tail = iv + MAX_IV_SIZE;
1469+
dctx = (struct tls_decrypt_ctx *)(mem + aead_size);
1470+
sgin = &dctx->sg[0];
1471+
sgout = &dctx->sg[n_sgin];
14721472

14731473
/* For CCM based ciphers, first byte of nonce+iv is a constant */
14741474
switch (prot->cipher_type) {
14751475
case TLS_CIPHER_AES_CCM_128:
1476-
iv[0] = TLS_AES_CCM_IV_B0_BYTE;
1476+
dctx->iv[0] = TLS_AES_CCM_IV_B0_BYTE;
14771477
iv_offset = 1;
14781478
break;
14791479
case TLS_CIPHER_SM4_CCM:
1480-
iv[0] = TLS_SM4_CCM_IV_B0_BYTE;
1480+
dctx->iv[0] = TLS_SM4_CCM_IV_B0_BYTE;
14811481
iv_offset = 1;
14821482
break;
14831483
}
14841484

14851485
/* Prepare IV */
14861486
if (prot->version == TLS_1_3_VERSION ||
14871487
prot->cipher_type == TLS_CIPHER_CHACHA20_POLY1305) {
1488-
memcpy(iv + iv_offset, tls_ctx->rx.iv,
1488+
memcpy(&dctx->iv[iv_offset], tls_ctx->rx.iv,
14891489
prot->iv_size + prot->salt_size);
14901490
} else {
14911491
err = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE,
1492-
iv + iv_offset + prot->salt_size,
1492+
&dctx->iv[iv_offset] + prot->salt_size,
14931493
prot->iv_size);
14941494
if (err < 0) {
14951495
kfree(mem);
14961496
return err;
14971497
}
1498-
memcpy(iv + iv_offset, tls_ctx->rx.iv, prot->salt_size);
1498+
memcpy(&dctx->iv[iv_offset], tls_ctx->rx.iv, prot->salt_size);
14991499
}
1500-
xor_iv_with_seq(prot, iv + iv_offset, tls_ctx->rx.rec_seq);
1500+
xor_iv_with_seq(prot, &dctx->iv[iv_offset], tls_ctx->rx.rec_seq);
15011501

15021502
/* Prepare AAD */
1503-
tls_make_aad(aad, rxm->full_len - prot->overhead_size +
1503+
tls_make_aad(dctx->aad, rxm->full_len - prot->overhead_size +
15041504
prot->tail_size,
15051505
tls_ctx->rx.rec_seq, tlm->control, prot);
15061506

15071507
/* Prepare sgin */
15081508
sg_init_table(sgin, n_sgin);
1509-
sg_set_buf(&sgin[0], aad, prot->aad_size);
1509+
sg_set_buf(&sgin[0], dctx->aad, prot->aad_size);
15101510
err = skb_to_sgvec(skb, &sgin[1],
15111511
rxm->offset + prot->prepend_size,
15121512
rxm->full_len - prot->prepend_size);
@@ -1518,7 +1518,7 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
15181518
if (n_sgout) {
15191519
if (out_iov) {
15201520
sg_init_table(sgout, n_sgout);
1521-
sg_set_buf(&sgout[0], aad, prot->aad_size);
1521+
sg_set_buf(&sgout[0], dctx->aad, prot->aad_size);
15221522

15231523
err = tls_setup_from_iter(out_iov, data_len,
15241524
&pages, &sgout[1],
@@ -1528,7 +1528,7 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
15281528

15291529
if (prot->tail_size) {
15301530
sg_unmark_end(&sgout[pages]);
1531-
sg_set_buf(&sgout[pages + 1], tail,
1531+
sg_set_buf(&sgout[pages + 1], &dctx->tail,
15321532
prot->tail_size);
15331533
sg_mark_end(&sgout[pages + 1]);
15341534
}
@@ -1545,13 +1545,13 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
15451545
}
15461546

15471547
/* Prepare and submit AEAD request */
1548-
err = tls_do_decryption(sk, skb, sgin, sgout, iv,
1548+
err = tls_do_decryption(sk, skb, sgin, sgout, dctx->iv,
15491549
data_len + prot->tail_size, aead_req, darg);
15501550
if (darg->async)
15511551
return 0;
15521552

15531553
if (prot->tail_size)
1554-
darg->tail = *tail;
1554+
darg->tail = dctx->tail;
15551555

15561556
/* Release the pages in case iov was mapped to pages */
15571557
for (; pages > 0; pages--)

0 commit comments

Comments
 (0)