Skip to content

Commit 4509de1

Browse files
nxa22042davem330
authored andcommitted
net/tls: Move protocol constants from cipher context to tls context
Each tls context maintains two cipher contexts (one each for tx and rx directions). For each tls session, the constants such as protocol version, ciphersuite, iv size, associated data size etc are same for both the directions and need to be stored only once per tls context. Hence these are moved from 'struct cipher_context' to 'struct tls_prot_info' and stored only once in 'struct tls_context'. Signed-off-by: Vakul Garg <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c9b747d commit 4509de1

File tree

4 files changed

+149
-110
lines changed

4 files changed

+149
-110
lines changed

include/net/tls.h

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,8 @@ enum {
199199
};
200200

201201
struct cipher_context {
202-
u16 prepend_size;
203-
u16 tag_size;
204-
u16 overhead_size;
205-
u16 iv_size;
206202
char *iv;
207-
u16 rec_seq_size;
208203
char *rec_seq;
209-
u16 aad_size;
210-
u16 tail_size;
211204
};
212205

213206
union tls_crypto_context {
@@ -218,7 +211,21 @@ union tls_crypto_context {
218211
};
219212
};
220213

214+
struct tls_prot_info {
215+
u16 version;
216+
u16 cipher_type;
217+
u16 prepend_size;
218+
u16 tag_size;
219+
u16 overhead_size;
220+
u16 iv_size;
221+
u16 rec_seq_size;
222+
u16 aad_size;
223+
u16 tail_size;
224+
};
225+
221226
struct tls_context {
227+
struct tls_prot_info prot_info;
228+
222229
union tls_crypto_context crypto_send;
223230
union tls_crypto_context crypto_recv;
224231

@@ -401,16 +408,26 @@ static inline bool tls_bigint_increment(unsigned char *seq, int len)
401408
return (i == -1);
402409
}
403410

411+
static inline struct tls_context *tls_get_ctx(const struct sock *sk)
412+
{
413+
struct inet_connection_sock *icsk = inet_csk(sk);
414+
415+
return icsk->icsk_ulp_data;
416+
}
417+
404418
static inline void tls_advance_record_sn(struct sock *sk,
405419
struct cipher_context *ctx,
406420
int version)
407421
{
408-
if (tls_bigint_increment(ctx->rec_seq, ctx->rec_seq_size))
422+
struct tls_context *tls_ctx = tls_get_ctx(sk);
423+
struct tls_prot_info *prot = &tls_ctx->prot_info;
424+
425+
if (tls_bigint_increment(ctx->rec_seq, prot->rec_seq_size))
409426
tls_err_abort(sk, EBADMSG);
410427

411428
if (version != TLS_1_3_VERSION) {
412429
tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
413-
ctx->iv_size);
430+
prot->iv_size);
414431
}
415432
}
416433

@@ -420,9 +437,10 @@ static inline void tls_fill_prepend(struct tls_context *ctx,
420437
unsigned char record_type,
421438
int version)
422439
{
423-
size_t pkt_len, iv_size = ctx->tx.iv_size;
440+
struct tls_prot_info *prot = &ctx->prot_info;
441+
size_t pkt_len, iv_size = prot->iv_size;
424442

425-
pkt_len = plaintext_len + ctx->tx.tag_size;
443+
pkt_len = plaintext_len + prot->tag_size;
426444
if (version != TLS_1_3_VERSION) {
427445
pkt_len += iv_size;
428446

@@ -475,12 +493,6 @@ static inline void xor_iv_with_seq(int version, char *iv, char *seq)
475493
}
476494
}
477495

478-
static inline struct tls_context *tls_get_ctx(const struct sock *sk)
479-
{
480-
struct inet_connection_sock *icsk = inet_csk(sk);
481-
482-
return icsk->icsk_ulp_data;
483-
}
484496

485497
static inline struct tls_sw_context_rx *tls_sw_ctx_rx(
486498
const struct tls_context *tls_ctx)

net/tls/tls_device.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ static int tls_push_record(struct sock *sk,
247247
int flags,
248248
unsigned char record_type)
249249
{
250+
struct tls_prot_info *prot = &ctx->prot_info;
250251
struct tcp_sock *tp = tcp_sk(sk);
251252
struct page_frag dummy_tag_frag;
252253
skb_frag_t *frag;
@@ -256,15 +257,15 @@ static int tls_push_record(struct sock *sk,
256257
frag = &record->frags[0];
257258
tls_fill_prepend(ctx,
258259
skb_frag_address(frag),
259-
record->len - ctx->tx.prepend_size,
260+
record->len - prot->prepend_size,
260261
record_type,
261262
ctx->crypto_send.info.version);
262263

263264
/* HW doesn't care about the data in the tag, because it fills it. */
264265
dummy_tag_frag.page = skb_frag_page(frag);
265266
dummy_tag_frag.offset = 0;
266267

267-
tls_append_frag(record, &dummy_tag_frag, ctx->tx.tag_size);
268+
tls_append_frag(record, &dummy_tag_frag, prot->tag_size);
268269
record->end_seq = tp->write_seq + record->len;
269270
spin_lock_irq(&offload_ctx->lock);
270271
list_add_tail(&record->list, &offload_ctx->records_list);
@@ -347,6 +348,7 @@ static int tls_push_data(struct sock *sk,
347348
unsigned char record_type)
348349
{
349350
struct tls_context *tls_ctx = tls_get_ctx(sk);
351+
struct tls_prot_info *prot = &tls_ctx->prot_info;
350352
struct tls_offload_context_tx *ctx = tls_offload_ctx_tx(tls_ctx);
351353
int tls_push_record_flags = flags | MSG_SENDPAGE_NOTLAST;
352354
int more = flags & (MSG_SENDPAGE_NOTLAST | MSG_MORE);
@@ -376,10 +378,10 @@ static int tls_push_data(struct sock *sk,
376378
* we need to leave room for an authentication tag.
377379
*/
378380
max_open_record_len = TLS_MAX_PAYLOAD_SIZE +
379-
tls_ctx->tx.prepend_size;
381+
prot->prepend_size;
380382
do {
381383
rc = tls_do_allocation(sk, ctx, pfrag,
382-
tls_ctx->tx.prepend_size);
384+
prot->prepend_size);
383385
if (rc) {
384386
rc = sk_stream_wait_memory(sk, &timeo);
385387
if (!rc)
@@ -397,7 +399,7 @@ static int tls_push_data(struct sock *sk,
397399
size = orig_size;
398400
destroy_record(record);
399401
ctx->open_record = NULL;
400-
} else if (record->len > tls_ctx->tx.prepend_size) {
402+
} else if (record->len > prot->prepend_size) {
401403
goto last_record;
402404
}
403405

@@ -658,6 +660,8 @@ int tls_device_decrypted(struct sock *sk, struct sk_buff *skb)
658660
int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
659661
{
660662
u16 nonce_size, tag_size, iv_size, rec_seq_size;
663+
struct tls_context *tls_ctx = tls_get_ctx(sk);
664+
struct tls_prot_info *prot = &tls_ctx->prot_info;
661665
struct tls_record_info *start_marker_record;
662666
struct tls_offload_context_tx *offload_ctx;
663667
struct tls_crypto_info *crypto_info;
@@ -703,10 +707,10 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
703707
goto free_offload_ctx;
704708
}
705709

706-
ctx->tx.prepend_size = TLS_HEADER_SIZE + nonce_size;
707-
ctx->tx.tag_size = tag_size;
708-
ctx->tx.overhead_size = ctx->tx.prepend_size + ctx->tx.tag_size;
709-
ctx->tx.iv_size = iv_size;
710+
prot->prepend_size = TLS_HEADER_SIZE + nonce_size;
711+
prot->tag_size = tag_size;
712+
prot->overhead_size = prot->prepend_size + prot->tag_size;
713+
prot->iv_size = iv_size;
710714
ctx->tx.iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
711715
GFP_KERNEL);
712716
if (!ctx->tx.iv) {
@@ -716,7 +720,7 @@ int tls_set_device_offload(struct sock *sk, struct tls_context *ctx)
716720

717721
memcpy(ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size);
718722

719-
ctx->tx.rec_seq_size = rec_seq_size;
723+
prot->rec_seq_size = rec_seq_size;
720724
ctx->tx.rec_seq = kmemdup(rec_seq, rec_seq_size, GFP_KERNEL);
721725
if (!ctx->tx.rec_seq) {
722726
rc = -ENOMEM;

net/tls/tls_main.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
435435
unsigned int optlen, int tx)
436436
{
437437
struct tls_crypto_info *crypto_info;
438+
struct tls_crypto_info *alt_crypto_info;
438439
struct tls_context *ctx = tls_get_ctx(sk);
439440
size_t optsize;
440441
int rc = 0;
@@ -445,10 +446,13 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
445446
goto out;
446447
}
447448

448-
if (tx)
449+
if (tx) {
449450
crypto_info = &ctx->crypto_send.info;
450-
else
451+
alt_crypto_info = &ctx->crypto_recv.info;
452+
} else {
451453
crypto_info = &ctx->crypto_recv.info;
454+
alt_crypto_info = &ctx->crypto_send.info;
455+
}
452456

453457
/* Currently we don't support set crypto info more than one time */
454458
if (TLS_CRYPTO_INFO_READY(crypto_info)) {
@@ -469,6 +473,15 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
469473
goto err_crypto_info;
470474
}
471475

476+
/* Ensure that TLS version and ciphers are same in both directions */
477+
if (TLS_CRYPTO_INFO_READY(alt_crypto_info)) {
478+
if (alt_crypto_info->version != crypto_info->version ||
479+
alt_crypto_info->cipher_type != crypto_info->cipher_type) {
480+
rc = -EINVAL;
481+
goto err_crypto_info;
482+
}
483+
}
484+
472485
switch (crypto_info->cipher_type) {
473486
case TLS_CIPHER_AES_GCM_128:
474487
case TLS_CIPHER_AES_GCM_256: {

0 commit comments

Comments
 (0)