mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									fedf201e12
								
							
						
					
					
						commit
						130b392c6c
					
				
					 6 changed files with 154 additions and 43 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (version != TLS_1_3_VERSION) {
 | 
				
			||||||
		tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
 | 
							tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
 | 
				
			||||||
				     ctx->iv_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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (version != TLS_1_3_VERSION) {
 | 
				
			||||||
		memcpy(buf, record_sequence, record_sequence_size);
 | 
							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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										110
									
								
								net/tls/tls_sw.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								net/tls/tls_sw.c
									
									
									
									
									
								
							| 
						 | 
					@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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));
 | 
							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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						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);
 | 
							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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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->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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue