Commit 510128b3 authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by David S. Miller
Browse files

tls: add counters for rekey



This introduces 5 counters to keep track of key updates:
Tls{Rx,Tx}Rekey{Ok,Error} and TlsRxRekeyReceived.

Suggested-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 47069594
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -358,6 +358,11 @@ enum
	LINUX_MIB_TLSRXDEVICERESYNC,		/* TlsRxDeviceResync */
	LINUX_MIB_TLSDECRYPTRETRY,		/* TlsDecryptRetry */
	LINUX_MIB_TLSRXNOPADVIOL,		/* TlsRxNoPadViolation */
	LINUX_MIB_TLSRXREKEYOK,			/* TlsRxRekeyOk */
	LINUX_MIB_TLSRXREKEYERROR,		/* TlsRxRekeyError */
	LINUX_MIB_TLSTXREKEYOK,			/* TlsTxRekeyOk */
	LINUX_MIB_TLSTXREKEYERROR,		/* TlsTxRekeyError */
	LINUX_MIB_TLSRXREKEYRECEIVED,		/* TlsRxRekeyReceived */
	__LINUX_MIB_TLSMAX
};

+22 −5
Original line number Diff line number Diff line
@@ -640,8 +640,11 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
		/* Currently we only support setting crypto info more
		 * than one time for TLS 1.3
		 */
		if (crypto_info->version != TLS_1_3_VERSION)
		if (crypto_info->version != TLS_1_3_VERSION) {
			TLS_INC_STATS(sock_net(sk), tx ? LINUX_MIB_TLSTXREKEYERROR
						       : LINUX_MIB_TLSRXREKEYERROR);
			return -EBUSY;
		}

		update = true;
		old_crypto_info = crypto_info;
@@ -696,8 +699,13 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
						update ? crypto_info : NULL);
			if (rc)
				goto err_crypto_info;

			if (update) {
				TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSTXREKEYOK);
			} else {
				TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSTXSW);
				TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRTXSW);
			}
			conf = TLS_SW;
		}
	} else {
@@ -711,8 +719,13 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
						update ? crypto_info : NULL);
			if (rc)
				goto err_crypto_info;

			if (update) {
				TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXREKEYOK);
			} else {
				TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXSW);
				TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSCURRRXSW);
			}
			conf = TLS_SW;
		}
		if (!update)
@@ -735,6 +748,10 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
	return 0;

err_crypto_info:
	if (update) {
		TLS_INC_STATS(sock_net(sk), tx ? LINUX_MIB_TLSTXREKEYERROR
					       : LINUX_MIB_TLSRXREKEYERROR);
	}
	memzero_explicit(crypto_ctx, sizeof(*crypto_ctx));
	return rc;
}
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,11 @@ static const struct snmp_mib tls_mib_list[] = {
	SNMP_MIB_ITEM("TlsRxDeviceResync", LINUX_MIB_TLSRXDEVICERESYNC),
	SNMP_MIB_ITEM("TlsDecryptRetry", LINUX_MIB_TLSDECRYPTRETRY),
	SNMP_MIB_ITEM("TlsRxNoPadViolation", LINUX_MIB_TLSRXNOPADVIOL),
	SNMP_MIB_ITEM("TlsRxRekeyOk", LINUX_MIB_TLSRXREKEYOK),
	SNMP_MIB_ITEM("TlsRxRekeyError", LINUX_MIB_TLSRXREKEYERROR),
	SNMP_MIB_ITEM("TlsTxRekeyOk", LINUX_MIB_TLSTXREKEYOK),
	SNMP_MIB_ITEM("TlsTxRekeyError", LINUX_MIB_TLSTXREKEYERROR),
	SNMP_MIB_ITEM("TlsRxRekeyReceived", LINUX_MIB_TLSRXREKEYRECEIVED),
	SNMP_MIB_SENTINEL
};

+4 −2
Original line number Diff line number Diff line
@@ -1724,7 +1724,8 @@ tls_decrypt_device(struct sock *sk, struct msghdr *msg,
	return 1;
}

static int tls_check_pending_rekey(struct tls_context *ctx, struct sk_buff *skb)
static int tls_check_pending_rekey(struct sock *sk, struct tls_context *ctx,
				   struct sk_buff *skb)
{
	const struct strp_msg *rxm = strp_msg(skb);
	const struct tls_msg *tlm = tls_msg(skb);
@@ -1747,6 +1748,7 @@ static int tls_check_pending_rekey(struct tls_context *ctx, struct sk_buff *skb)
		struct tls_sw_context_rx *rx_ctx = ctx->priv_ctx_rx;

		WRITE_ONCE(rx_ctx->key_update_pending, true);
		TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXREKEYRECEIVED);
	}

	return 0;
@@ -1771,7 +1773,7 @@ static int tls_rx_one_record(struct sock *sk, struct msghdr *msg,
	rxm->full_len -= prot->overhead_size;
	tls_advance_record_sn(sk, prot, &tls_ctx->rx);

	return tls_check_pending_rekey(tls_ctx, darg->skb);
	return tls_check_pending_rekey(sk, tls_ctx, darg->skb);
}

int decrypt_skb(struct sock *sk, struct scatterlist *sgout)