net: tls: Add tls 1.3 support

TLS 1.3 has minor changes from TLS 1.2 at the record layer.

* Header now hardcodes the same version and application content type in
  the header.
* The real content type is appended after the data, before encryption (or
  after decryption).
* The IV is xored with the sequence number, instead of concatinating four
  bytes of IV with the explicit IV.
* Zero-padding:  No exlicit length is given, we search backwards from the
  end of the decrypted data for the first non-zero byte, which is the
  content type.  Currently recv supports reading zero-padding, but there
  is no way for send to add zero padding.

Signed-off-by: Dave Watson <davejwatson@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Dave Watson 2019-01-30 21:58:31 +00:00 committed by David S. Miller
parent fedf201e12
commit 130b392c6c
6 changed files with 154 additions and 43 deletions

View File

@ -119,6 +119,9 @@ struct tls_rec {
/* AAD | msg_encrypted.sg.data (data contains overhead for hdr & iv & tag) */ /* AAD | msg_encrypted.sg.data (data contains overhead for hdr & iv & tag) */
struct scatterlist sg_aead_out[2]; struct scatterlist sg_aead_out[2];
char content_type;
struct scatterlist sg_content_type;
char aad_space[TLS_AAD_SPACE_SIZE]; char aad_space[TLS_AAD_SPACE_SIZE];
u8 iv_data[TLS_CIPHER_AES_GCM_128_IV_SIZE + u8 iv_data[TLS_CIPHER_AES_GCM_128_IV_SIZE +
TLS_CIPHER_AES_GCM_128_SALT_SIZE]; TLS_CIPHER_AES_GCM_128_SALT_SIZE];
@ -203,6 +206,7 @@ struct cipher_context {
u16 rec_seq_size; u16 rec_seq_size;
char *rec_seq; char *rec_seq;
u16 aad_size; u16 aad_size;
u16 tail_size;
}; };
union tls_crypto_context { union tls_crypto_context {
@ -397,49 +401,77 @@ static inline bool tls_bigint_increment(unsigned char *seq, int len)
} }
static inline void tls_advance_record_sn(struct sock *sk, static inline void tls_advance_record_sn(struct sock *sk,
struct cipher_context *ctx) struct cipher_context *ctx,
int version)
{ {
if (tls_bigint_increment(ctx->rec_seq, ctx->rec_seq_size)) if (tls_bigint_increment(ctx->rec_seq, ctx->rec_seq_size))
tls_err_abort(sk, EBADMSG); tls_err_abort(sk, EBADMSG);
tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
ctx->iv_size); if (version != TLS_1_3_VERSION) {
tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
ctx->iv_size);
}
} }
static inline void tls_fill_prepend(struct tls_context *ctx, static inline void tls_fill_prepend(struct tls_context *ctx,
char *buf, char *buf,
size_t plaintext_len, size_t plaintext_len,
unsigned char record_type) unsigned char record_type,
int version)
{ {
size_t pkt_len, iv_size = ctx->tx.iv_size; size_t pkt_len, iv_size = ctx->tx.iv_size;
pkt_len = plaintext_len + iv_size + ctx->tx.tag_size; pkt_len = plaintext_len + ctx->tx.tag_size;
if (version != TLS_1_3_VERSION) {
pkt_len += iv_size;
memcpy(buf + TLS_NONCE_OFFSET,
ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv_size);
}
/* we cover nonce explicit here as well, so buf should be of /* we cover nonce explicit here as well, so buf should be of
* size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE * size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE
*/ */
buf[0] = record_type; buf[0] = version == TLS_1_3_VERSION ?
buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.info.version); TLS_RECORD_TYPE_DATA : record_type;
buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.info.version); /* Note that VERSION must be TLS_1_2 for both TLS1.2 and TLS1.3 */
buf[1] = TLS_1_2_VERSION_MINOR;
buf[2] = TLS_1_2_VERSION_MAJOR;
/* we can use IV for nonce explicit according to spec */ /* we can use IV for nonce explicit according to spec */
buf[3] = pkt_len >> 8; buf[3] = pkt_len >> 8;
buf[4] = pkt_len & 0xFF; buf[4] = pkt_len & 0xFF;
memcpy(buf + TLS_NONCE_OFFSET,
ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv_size);
} }
static inline void tls_make_aad(char *buf, static inline void tls_make_aad(char *buf,
size_t size, size_t size,
char *record_sequence, char *record_sequence,
int record_sequence_size, int record_sequence_size,
unsigned char record_type) unsigned char record_type,
int version)
{ {
memcpy(buf, record_sequence, record_sequence_size); if (version != TLS_1_3_VERSION) {
memcpy(buf, record_sequence, record_sequence_size);
buf += 8;
} else {
size += TLS_CIPHER_AES_GCM_128_TAG_SIZE;
}
buf[8] = record_type; buf[0] = version == TLS_1_3_VERSION ?
buf[9] = TLS_1_2_VERSION_MAJOR; TLS_RECORD_TYPE_DATA : record_type;
buf[10] = TLS_1_2_VERSION_MINOR; buf[1] = TLS_1_2_VERSION_MAJOR;
buf[11] = size >> 8; buf[2] = TLS_1_2_VERSION_MINOR;
buf[12] = size & 0xFF; buf[3] = size >> 8;
buf[4] = size & 0xFF;
}
static inline void xor_iv_with_seq(int version, char *iv, char *seq)
{
int i;
if (version == TLS_1_3_VERSION) {
for (i = 0; i < 8; i++)
iv[i + 4] ^= seq[i];
}
} }
static inline struct tls_context *tls_get_ctx(const struct sock *sk) static inline struct tls_context *tls_get_ctx(const struct sock *sk)

View File

@ -51,6 +51,10 @@
#define TLS_1_2_VERSION_MINOR 0x3 #define TLS_1_2_VERSION_MINOR 0x3
#define TLS_1_2_VERSION TLS_VERSION_NUMBER(TLS_1_2) #define TLS_1_2_VERSION TLS_VERSION_NUMBER(TLS_1_2)
#define TLS_1_3_VERSION_MAJOR 0x3
#define TLS_1_3_VERSION_MINOR 0x4
#define TLS_1_3_VERSION TLS_VERSION_NUMBER(TLS_1_3)
/* Supported ciphers */ /* Supported ciphers */
#define TLS_CIPHER_AES_GCM_128 51 #define TLS_CIPHER_AES_GCM_128 51
#define TLS_CIPHER_AES_GCM_128_IV_SIZE 8 #define TLS_CIPHER_AES_GCM_128_IV_SIZE 8

View File

@ -257,7 +257,8 @@ static int tls_push_record(struct sock *sk,
tls_fill_prepend(ctx, tls_fill_prepend(ctx,
skb_frag_address(frag), skb_frag_address(frag),
record->len - ctx->tx.prepend_size, record->len - ctx->tx.prepend_size,
record_type); record_type,
ctx->crypto_send.info.version);
/* HW doesn't care about the data in the tag, because it fills it. */ /* HW doesn't care about the data in the tag, because it fills it. */
dummy_tag_frag.page = skb_frag_page(frag); dummy_tag_frag.page = skb_frag_page(frag);
@ -270,7 +271,7 @@ static int tls_push_record(struct sock *sk,
spin_unlock_irq(&offload_ctx->lock); spin_unlock_irq(&offload_ctx->lock);
offload_ctx->open_record = NULL; offload_ctx->open_record = NULL;
set_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags); set_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags);
tls_advance_record_sn(sk, &ctx->tx); tls_advance_record_sn(sk, &ctx->tx, ctx->crypto_send.info.version);
for (i = 0; i < record->num_frags; i++) { for (i = 0; i < record->num_frags; i++) {
frag = &record->frags[i]; frag = &record->frags[i];

View File

@ -73,7 +73,8 @@ static int tls_enc_record(struct aead_request *aead_req,
len -= TLS_CIPHER_AES_GCM_128_IV_SIZE; len -= TLS_CIPHER_AES_GCM_128_IV_SIZE;
tls_make_aad(aad, len - TLS_CIPHER_AES_GCM_128_TAG_SIZE, tls_make_aad(aad, len - TLS_CIPHER_AES_GCM_128_TAG_SIZE,
(char *)&rcd_sn, sizeof(rcd_sn), buf[0]); (char *)&rcd_sn, sizeof(rcd_sn), buf[0],
TLS_1_2_VERSION);
memcpy(iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, buf + TLS_HEADER_SIZE, memcpy(iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, buf + TLS_HEADER_SIZE,
TLS_CIPHER_AES_GCM_128_IV_SIZE); TLS_CIPHER_AES_GCM_128_IV_SIZE);

View File

@ -463,7 +463,8 @@ static int do_tls_setsockopt_conf(struct sock *sk, char __user *optval,
} }
/* check version */ /* check version */
if (crypto_info->version != TLS_1_2_VERSION) { if (crypto_info->version != TLS_1_2_VERSION &&
crypto_info->version != TLS_1_3_VERSION) {
rc = -ENOTSUPP; rc = -ENOTSUPP;
goto err_crypto_info; goto err_crypto_info;
} }

View File

@ -120,6 +120,34 @@ static int skb_nsg(struct sk_buff *skb, int offset, int len)
return __skb_nsg(skb, offset, len, 0); return __skb_nsg(skb, offset, len, 0);
} }
static int padding_length(struct tls_sw_context_rx *ctx,
struct tls_context *tls_ctx, struct sk_buff *skb)
{
struct strp_msg *rxm = strp_msg(skb);
int sub = 0;
/* Determine zero-padding length */
if (tls_ctx->crypto_recv.info.version == TLS_1_3_VERSION) {
char content_type = 0;
int err;
int back = 17;
while (content_type == 0) {
if (back > rxm->full_len)
return -EBADMSG;
err = skb_copy_bits(skb,
rxm->offset + rxm->full_len - back,
&content_type, 1);
if (content_type)
break;
sub++;
back++;
}
ctx->control = content_type;
}
return sub;
}
static void tls_decrypt_done(struct crypto_async_request *req, int err) static void tls_decrypt_done(struct crypto_async_request *req, int err)
{ {
struct aead_request *aead_req = (struct aead_request *)req; struct aead_request *aead_req = (struct aead_request *)req;
@ -142,7 +170,7 @@ static void tls_decrypt_done(struct crypto_async_request *req, int err)
tls_err_abort(skb->sk, err); tls_err_abort(skb->sk, err);
} else { } else {
struct strp_msg *rxm = strp_msg(skb); struct strp_msg *rxm = strp_msg(skb);
rxm->full_len -= padding_length(ctx, tls_ctx, skb);
rxm->offset += tls_ctx->rx.prepend_size; rxm->offset += tls_ctx->rx.prepend_size;
rxm->full_len -= tls_ctx->rx.overhead_size; rxm->full_len -= tls_ctx->rx.overhead_size;
} }
@ -448,6 +476,8 @@ static int tls_do_encryption(struct sock *sk,
int rc; int rc;
memcpy(rec->iv_data, tls_ctx->tx.iv, sizeof(rec->iv_data)); memcpy(rec->iv_data, tls_ctx->tx.iv, sizeof(rec->iv_data));
xor_iv_with_seq(tls_ctx->crypto_send.info.version, rec->iv_data,
tls_ctx->tx.rec_seq);
sge->offset += tls_ctx->tx.prepend_size; sge->offset += tls_ctx->tx.prepend_size;
sge->length -= tls_ctx->tx.prepend_size; sge->length -= tls_ctx->tx.prepend_size;
@ -483,7 +513,8 @@ static int tls_do_encryption(struct sock *sk,
/* Unhook the record from context if encryption is not failure */ /* Unhook the record from context if encryption is not failure */
ctx->open_rec = NULL; ctx->open_rec = NULL;
tls_advance_record_sn(sk, &tls_ctx->tx); tls_advance_record_sn(sk, &tls_ctx->tx,
tls_ctx->crypto_send.info.version);
return rc; return rc;
} }
@ -640,7 +671,17 @@ static int tls_push_record(struct sock *sk, int flags,
i = msg_pl->sg.end; i = msg_pl->sg.end;
sk_msg_iter_var_prev(i); sk_msg_iter_var_prev(i);
sg_mark_end(sk_msg_elem(msg_pl, i));
rec->content_type = record_type;
if (tls_ctx->crypto_send.info.version == TLS_1_3_VERSION) {
/* Add content type to end of message. No padding added */
sg_set_buf(&rec->sg_content_type, &rec->content_type, 1);
sg_mark_end(&rec->sg_content_type);
sg_chain(msg_pl->sg.data, msg_pl->sg.end + 1,
&rec->sg_content_type);
} else {
sg_mark_end(sk_msg_elem(msg_pl, i));
}
i = msg_pl->sg.start; i = msg_pl->sg.start;
sg_chain(rec->sg_aead_in, 2, rec->inplace_crypto ? sg_chain(rec->sg_aead_in, 2, rec->inplace_crypto ?
@ -653,18 +694,22 @@ static int tls_push_record(struct sock *sk, int flags,
i = msg_en->sg.start; i = msg_en->sg.start;
sg_chain(rec->sg_aead_out, 2, &msg_en->sg.data[i]); sg_chain(rec->sg_aead_out, 2, &msg_en->sg.data[i]);
tls_make_aad(rec->aad_space, msg_pl->sg.size, tls_make_aad(rec->aad_space, msg_pl->sg.size + tls_ctx->tx.tail_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_ctx->crypto_send.info.version);
tls_fill_prepend(tls_ctx, tls_fill_prepend(tls_ctx,
page_address(sg_page(&msg_en->sg.data[i])) + page_address(sg_page(&msg_en->sg.data[i])) +
msg_en->sg.data[i].offset, msg_pl->sg.size, msg_en->sg.data[i].offset,
record_type); msg_pl->sg.size + tls_ctx->tx.tail_size,
record_type,
tls_ctx->crypto_send.info.version);
tls_ctx->pending_open_record_frags = false; tls_ctx->pending_open_record_frags = false;
rc = tls_do_encryption(sk, tls_ctx, ctx, req, msg_pl->sg.size, i); rc = tls_do_encryption(sk, tls_ctx, ctx, req,
msg_pl->sg.size + tls_ctx->tx.tail_size, i);
if (rc < 0) { if (rc < 0) {
if (rc != -EINPROGRESS) { if (rc != -EINPROGRESS) {
tls_err_abort(sk, EBADMSG); tls_err_abort(sk, EBADMSG);
@ -1292,7 +1337,8 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
u8 *aad, *iv, *mem = NULL; u8 *aad, *iv, *mem = NULL;
struct scatterlist *sgin = NULL; struct scatterlist *sgin = NULL;
struct scatterlist *sgout = NULL; struct scatterlist *sgout = NULL;
const int data_len = rxm->full_len - tls_ctx->rx.overhead_size; const int data_len = rxm->full_len - tls_ctx->rx.overhead_size +
tls_ctx->rx.tail_size;
if (*zc && (out_iov || out_sg)) { if (*zc && (out_iov || out_sg)) {
if (out_iov) if (out_iov)
@ -1343,12 +1389,20 @@ static int decrypt_internal(struct sock *sk, struct sk_buff *skb,
kfree(mem); kfree(mem);
return err; return err;
} }
memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); if (tls_ctx->crypto_recv.info.version == TLS_1_3_VERSION)
memcpy(iv, tls_ctx->rx.iv, crypto_aead_ivsize(ctx->aead_recv));
else
memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
xor_iv_with_seq(tls_ctx->crypto_recv.info.version, iv,
tls_ctx->rx.rec_seq);
/* Prepare AAD */ /* Prepare AAD */
tls_make_aad(aad, rxm->full_len - tls_ctx->rx.overhead_size, tls_make_aad(aad, rxm->full_len - tls_ctx->rx.overhead_size +
tls_ctx->rx.tail_size,
tls_ctx->rx.rec_seq, tls_ctx->rx.rec_seq_size, tls_ctx->rx.rec_seq, tls_ctx->rx.rec_seq_size,
ctx->control); ctx->control,
tls_ctx->crypto_recv.info.version);
/* Prepare sgin */ /* Prepare sgin */
sg_init_table(sgin, n_sgin); sg_init_table(sgin, n_sgin);
@ -1405,6 +1459,7 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
{ {
struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_context *tls_ctx = tls_get_ctx(sk);
struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
int version = tls_ctx->crypto_recv.info.version;
struct strp_msg *rxm = strp_msg(skb); struct strp_msg *rxm = strp_msg(skb);
int err = 0; int err = 0;
@ -1417,13 +1472,17 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb,
err = decrypt_internal(sk, skb, dest, NULL, chunk, zc, async); err = decrypt_internal(sk, skb, dest, NULL, chunk, zc, async);
if (err < 0) { if (err < 0) {
if (err == -EINPROGRESS) if (err == -EINPROGRESS)
tls_advance_record_sn(sk, &tls_ctx->rx); tls_advance_record_sn(sk, &tls_ctx->rx,
version);
return err; return err;
} }
rxm->full_len -= padding_length(ctx, tls_ctx, skb);
rxm->offset += tls_ctx->rx.prepend_size; rxm->offset += tls_ctx->rx.prepend_size;
rxm->full_len -= tls_ctx->rx.overhead_size; rxm->full_len -= tls_ctx->rx.overhead_size;
tls_advance_record_sn(sk, &tls_ctx->rx); tls_advance_record_sn(sk, &tls_ctx->rx, version);
ctx->decrypted = true; ctx->decrypted = true;
ctx->saved_data_ready(sk); ctx->saved_data_ready(sk);
} else { } else {
@ -1611,7 +1670,8 @@ int tls_sw_recvmsg(struct sock *sk,
to_decrypt = rxm->full_len - tls_ctx->rx.overhead_size; to_decrypt = rxm->full_len - tls_ctx->rx.overhead_size;
if (to_decrypt <= len && !is_kvec && !is_peek && if (to_decrypt <= len && !is_kvec && !is_peek &&
ctx->control == TLS_RECORD_TYPE_DATA) ctx->control == TLS_RECORD_TYPE_DATA &&
tls_ctx->crypto_recv.info.version != TLS_1_3_VERSION)
zc = true; zc = true;
err = decrypt_skb_update(sk, skb, &msg->msg_iter, err = decrypt_skb_update(sk, skb, &msg->msg_iter,
@ -1835,9 +1895,12 @@ static int tls_read_size(struct strparser *strp, struct sk_buff *skb)
data_len = ((header[4] & 0xFF) | (header[3] << 8)); data_len = ((header[4] & 0xFF) | (header[3] << 8));
cipher_overhead = tls_ctx->rx.tag_size + tls_ctx->rx.iv_size; cipher_overhead = tls_ctx->rx.tag_size;
if (tls_ctx->crypto_recv.info.version != TLS_1_3_VERSION)
cipher_overhead += tls_ctx->rx.iv_size;
if (data_len > TLS_MAX_PAYLOAD_SIZE + cipher_overhead) { if (data_len > TLS_MAX_PAYLOAD_SIZE + cipher_overhead +
tls_ctx->rx.tail_size) {
ret = -EMSGSIZE; ret = -EMSGSIZE;
goto read_failure; goto read_failure;
} }
@ -1846,12 +1909,12 @@ static int tls_read_size(struct strparser *strp, struct sk_buff *skb)
goto read_failure; goto read_failure;
} }
if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.info.version) || /* Note that both TLS1.3 and TLS1.2 use TLS_1_2 version here */
header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.info.version)) { if (header[1] != TLS_1_2_VERSION_MINOR ||
header[2] != TLS_1_2_VERSION_MAJOR) {
ret = -EINVAL; ret = -EINVAL;
goto read_failure; goto read_failure;
} }
#ifdef CONFIG_TLS_DEVICE #ifdef CONFIG_TLS_DEVICE
handle_device_resync(strp->sk, TCP_SKB_CB(skb)->seq + rxm->offset, handle_device_resync(strp->sk, TCP_SKB_CB(skb)->seq + rxm->offset,
*(u64*)tls_ctx->rx.rec_seq); *(u64*)tls_ctx->rx.rec_seq);
@ -2100,10 +2163,19 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
goto free_priv; goto free_priv;
} }
cctx->aad_size = TLS_AAD_SPACE_SIZE; if (crypto_info->version == TLS_1_3_VERSION) {
nonce_size = 0;
cctx->aad_size = TLS_HEADER_SIZE;
cctx->tail_size = 1;
} else {
cctx->aad_size = TLS_AAD_SPACE_SIZE;
cctx->tail_size = 0;
}
cctx->prepend_size = TLS_HEADER_SIZE + nonce_size; cctx->prepend_size = TLS_HEADER_SIZE + nonce_size;
cctx->tag_size = tag_size; cctx->tag_size = tag_size;
cctx->overhead_size = cctx->prepend_size + cctx->tag_size; cctx->overhead_size = cctx->prepend_size + cctx->tag_size +
cctx->tail_size;
cctx->iv_size = iv_size; cctx->iv_size = iv_size;
cctx->iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE, cctx->iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
GFP_KERNEL); GFP_KERNEL);