aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/tls.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/tls.h')
-rw-r--r--include/net/tls.h118
1 files changed, 89 insertions, 29 deletions
diff --git a/include/net/tls.h b/include/net/tls.h
index 1486b60c4de8..9f4117ae2297 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -119,6 +119,9 @@ struct tls_rec {
/* 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];
@@ -126,6 +129,11 @@ struct tls_rec {
u8 aead_req_ctx[];
};
+struct tls_msg {
+ struct strp_msg rxm;
+ u8 control;
+};
+
struct tx_work {
struct delayed_work work;
struct sock *sk;
@@ -139,6 +147,7 @@ struct tls_sw_context_tx {
struct list_head tx_list;
atomic_t encrypt_pending;
int async_notify;
+ int async_capable;
#define BIT_TX_SCHEDULED 0
unsigned long tx_bitmask;
@@ -147,12 +156,13 @@ struct tls_sw_context_tx {
struct tls_sw_context_rx {
struct crypto_aead *aead_recv;
struct crypto_wait async_wait;
-
struct strparser strp;
+ struct sk_buff_head rx_list; /* list of decrypted 'data' records */
void (*saved_data_ready)(struct sock *sk);
struct sk_buff *recv_pkt;
u8 control;
+ int async_capable;
bool decrypted;
atomic_t decrypt_pending;
bool async_notify;
@@ -194,21 +204,33 @@ enum {
};
struct cipher_context {
- u16 prepend_size;
- u16 tag_size;
- u16 overhead_size;
- u16 iv_size;
char *iv;
- u16 rec_seq_size;
char *rec_seq;
};
union tls_crypto_context {
struct tls_crypto_info info;
- struct tls12_crypto_info_aes_gcm_128 aes_gcm_128;
+ union {
+ struct tls12_crypto_info_aes_gcm_128 aes_gcm_128;
+ struct tls12_crypto_info_aes_gcm_256 aes_gcm_256;
+ };
+};
+
+struct tls_prot_info {
+ u16 version;
+ u16 cipher_type;
+ u16 prepend_size;
+ u16 tag_size;
+ u16 overhead_size;
+ u16 iv_size;
+ u16 rec_seq_size;
+ u16 aad_size;
+ u16 tail_size;
};
struct tls_context {
+ struct tls_prot_info prot_info;
+
union tls_crypto_context crypto_send;
union tls_crypto_context crypto_recv;
@@ -316,6 +338,11 @@ int tls_push_partial_record(struct sock *sk, struct tls_context *ctx,
int tls_push_pending_closed_record(struct sock *sk, struct tls_context *ctx,
int flags, long *timeo);
+static inline struct tls_msg *tls_msg(struct sk_buff *skb)
+{
+ return (struct tls_msg *)strp_msg(skb);
+}
+
static inline bool tls_is_pending_closed_record(struct tls_context *ctx)
{
return test_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags);
@@ -391,59 +418,92 @@ static inline bool tls_bigint_increment(unsigned char *seq, int len)
return (i == -1);
}
+static inline struct tls_context *tls_get_ctx(const struct sock *sk)
+{
+ struct inet_connection_sock *icsk = inet_csk(sk);
+
+ return icsk->icsk_ulp_data;
+}
+
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))
+ struct tls_context *tls_ctx = tls_get_ctx(sk);
+ struct tls_prot_info *prot = &tls_ctx->prot_info;
+
+ if (tls_bigint_increment(ctx->rec_seq, prot->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,
+ prot->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;
+ struct tls_prot_info *prot = &ctx->prot_info;
+ size_t pkt_len, iv_size = prot->iv_size;
+
+ pkt_len = plaintext_len + prot->tag_size;
+ if (version != TLS_1_3_VERSION) {
+ pkt_len += iv_size;
- pkt_len = plaintext_len + iv_size + ctx->tx.tag_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)
{
- 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[9] = TLS_1_2_VERSION_MAJOR;
- buf[10] = TLS_1_2_VERSION_MINOR;
- buf[11] = size >> 8;
- buf[12] = size & 0xFF;
+ 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 struct tls_context *tls_get_ctx(const struct sock *sk)
+static inline void xor_iv_with_seq(int version, char *iv, char *seq)
{
- struct inet_connection_sock *icsk = inet_csk(sk);
+ int i;
- return icsk->icsk_ulp_data;
+ if (version == TLS_1_3_VERSION) {
+ for (i = 0; i < 8; i++)
+ iv[i + 4] ^= seq[i];
+ }
}
+
static inline struct tls_sw_context_rx *tls_sw_ctx_rx(
const struct tls_context *tls_ctx)
{