]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blobdiff - include/net/tls.h
xsk: fix umem memory leak on cleanup
[mirror_ubuntu-eoan-kernel.git] / include / net / tls.h
index 1486b60c4de8d130a6b6d41aad7192960c200b30..a5a938583295c0789df287c737b7a1c87556c9f1 100644 (file)
@@ -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;
@@ -189,26 +199,34 @@ struct tls_offload_context_tx {
        (ALIGN(sizeof(struct tls_offload_context_tx), sizeof(void *)) +        \
         TLS_DRIVER_STATE_SIZE)
 
-enum {
-       TLS_PENDING_CLOSED_RECORD
-};
-
 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;
 
@@ -313,12 +331,14 @@ int tls_push_sg(struct sock *sk, struct tls_context *ctx,
 int tls_push_partial_record(struct sock *sk, struct tls_context *ctx,
                            int flags);
 
-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)
+static inline bool tls_is_partially_sent_record(struct tls_context *ctx)
 {
-       return test_bit(TLS_PENDING_CLOSED_RECORD, &ctx->flags);
+       return !!ctx->partially_sent_record;
 }
 
 static inline int tls_complete_pending_work(struct sock *sk,
@@ -330,17 +350,12 @@ static inline int tls_complete_pending_work(struct sock *sk,
        if (unlikely(sk->sk_write_pending))
                rc = wait_on_pending_writer(sk, timeo);
 
-       if (!rc && tls_is_pending_closed_record(ctx))
-               rc = tls_push_pending_closed_record(sk, ctx, flags, timeo);
+       if (!rc && tls_is_partially_sent_record(ctx))
+               rc = tls_push_partial_record(sk, ctx, flags);
 
        return rc;
 }
 
-static inline bool tls_is_partially_sent_record(struct tls_context *ctx)
-{
-       return !!ctx->partially_sent_record;
-}
-
 static inline bool tls_is_pending_open_record(struct tls_context *tls_ctx)
 {
        return tls_ctx->pending_open_record_frags;
@@ -391,59 +406,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)
 {
@@ -471,6 +519,9 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
        return !!tls_sw_ctx_tx(ctx);
 }
 
+void tls_sw_write_space(struct sock *sk, struct tls_context *ctx);
+void tls_device_write_space(struct sock *sk, struct tls_context *ctx);
+
 static inline struct tls_offload_context_rx *
 tls_offload_ctx_rx(const struct tls_context *tls_ctx)
 {