/* AAD | msg_encrypted.sg.data (data contains overhead for hdr & iv & tag) */
struct scatterlist sg_aead_out[2];
+ char content_type;
+ struct scatterlist sg_content_type;
+
char aad_space[TLS_AAD_SPACE_SIZE];
u8 iv_data[TLS_CIPHER_AES_GCM_128_IV_SIZE +
TLS_CIPHER_AES_GCM_128_SALT_SIZE];
u16 rec_seq_size;
char *rec_seq;
u16 aad_size;
+ u16 tail_size;
};
union tls_crypto_context {
}
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))
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,
char *buf,
size_t plaintext_len,
- unsigned char record_type)
+ unsigned char record_type,
+ int version)
{
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
* size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE
*/
- buf[0] = record_type;
- buf[1] = TLS_VERSION_MINOR(ctx->crypto_send.info.version);
- buf[2] = TLS_VERSION_MAJOR(ctx->crypto_send.info.version);
+ buf[0] = version == TLS_1_3_VERSION ?
+ TLS_RECORD_TYPE_DATA : record_type;
+ /* 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 */
buf[3] = pkt_len >> 8;
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,
size_t size,
char *record_sequence,
int record_sequence_size,
- unsigned char record_type)
+ unsigned char record_type,
+ int version)
+{
+ 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[0] = version == TLS_1_3_VERSION ?
+ TLS_RECORD_TYPE_DATA : record_type;
+ buf[1] = TLS_1_2_VERSION_MAJOR;
+ buf[2] = TLS_1_2_VERSION_MINOR;
+ buf[3] = size >> 8;
+ buf[4] = size & 0xFF;
+}
+
+static inline void xor_iv_with_seq(int version, char *iv, char *seq)
{
- memcpy(buf, record_sequence, record_sequence_size);
+ int i;
- buf[8] = record_type;
- buf[9] = TLS_1_2_VERSION_MAJOR;
- buf[10] = TLS_1_2_VERSION_MINOR;
- buf[11] = size >> 8;
- buf[12] = size & 0xFF;
+ 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)
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)
{
struct aead_request *aead_req = (struct aead_request *)req;
tls_err_abort(skb->sk, err);
} else {
struct strp_msg *rxm = strp_msg(skb);
-
+ rxm->full_len -= padding_length(ctx, tls_ctx, skb);
rxm->offset += tls_ctx->rx.prepend_size;
rxm->full_len -= tls_ctx->rx.overhead_size;
}
int rc;
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->length -= tls_ctx->tx.prepend_size;
/* Unhook the record from context if encryption is not failure */
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;
}
i = msg_pl->sg.end;
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;
sg_chain(rec->sg_aead_in, 2, rec->inplace_crypto ?
i = msg_en->sg.start;
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,
- record_type);
+ record_type,
+ tls_ctx->crypto_send.info.version);
tls_fill_prepend(tls_ctx,
page_address(sg_page(&msg_en->sg.data[i])) +
- msg_en->sg.data[i].offset, msg_pl->sg.size,
- record_type);
+ msg_en->sg.data[i].offset,
+ msg_pl->sg.size + tls_ctx->tx.tail_size,
+ record_type,
+ tls_ctx->crypto_send.info.version);
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 != -EINPROGRESS) {
tls_err_abort(sk, EBADMSG);
u8 *aad, *iv, *mem = NULL;
struct scatterlist *sgin = 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 (out_iov)
kfree(mem);
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 */
- 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,
- ctx->control);
+ ctx->control,
+ tls_ctx->crypto_recv.info.version);
/* Prepare sgin */
sg_init_table(sgin, n_sgin);
{
struct tls_context *tls_ctx = tls_get_ctx(sk);
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);
int err = 0;
err = decrypt_internal(sk, skb, dest, NULL, chunk, zc, async);
if (err < 0) {
if (err == -EINPROGRESS)
- tls_advance_record_sn(sk, &tls_ctx->rx);
+ tls_advance_record_sn(sk, &tls_ctx->rx,
+ version);
return err;
}
+
+ rxm->full_len -= padding_length(ctx, tls_ctx, skb);
+
rxm->offset += tls_ctx->rx.prepend_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->saved_data_ready(sk);
} else {
to_decrypt = rxm->full_len - tls_ctx->rx.overhead_size;
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;
err = decrypt_skb_update(sk, skb, &msg->msg_iter,
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;
goto read_failure;
}
goto read_failure;
}
- if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.info.version) ||
- header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.info.version)) {
+ /* Note that both TLS1.3 and TLS1.2 use TLS_1_2 version here */
+ if (header[1] != TLS_1_2_VERSION_MINOR ||
+ header[2] != TLS_1_2_VERSION_MAJOR) {
ret = -EINVAL;
goto read_failure;
}
-
#ifdef CONFIG_TLS_DEVICE
handle_device_resync(strp->sk, TCP_SKB_CB(skb)->seq + rxm->offset,
*(u64*)tls_ctx->rx.rec_seq);
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->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 = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
GFP_KERNEL);