diff options
Diffstat (limited to 'include/net/tls.h')
| -rw-r--r-- | include/net/tls.h | 141 | 
1 files changed, 97 insertions, 44 deletions
diff --git a/include/net/tls.h b/include/net/tls.h index 2a6ac8d642af..a5a938583295 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -119,11 +119,21 @@ 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];  	struct aead_request aead_req;  	u8 aead_req_ctx[];  }; +struct tls_msg { +	struct strp_msg rxm; +	u8 control; +}; +  struct tx_work {  	struct delayed_work work;  	struct sock *sk; @@ -137,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; @@ -145,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; @@ -187,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; @@ -311,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, @@ -328,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; @@ -389,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)  { @@ -469,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)  {  |