Re: [PATCH BlueZ] mesh: Re-arrange replay protection check and add

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Applied with minor tweeks from Inga

On Wed, 2020-01-29 at 09:17 -0800, Brian Gix wrote:
> Re-arranged for efficientcy. Replay Protection was set up as an atomic
> check-and-add operation. Now we check the message early so we can
> discard it without taking further action, and only add it to the RPL
> once fully verified that it was authorized and addressed to us.
> ---
>  mesh/model.c | 23 +++++++++----------
>  mesh/net.c   | 62 ++++++++++++++++++++++++++--------------------------
>  mesh/net.h   |  7 +++---
>  3 files changed, 45 insertions(+), 47 deletions(-)
> 
> diff --git a/mesh/model.c b/mesh/model.c
> index 92a00496c..574b6621a 100644
> --- a/mesh/model.c
> +++ b/mesh/model.c
> @@ -964,10 +964,12 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
>  		/* Unicast and not addressed to us */
>  		return false;
>  
> -	clear_text = l_malloc(size);
> -	if (!clear_text)
> +	/* Don't process if already in RPL */
> +	crpl = node_get_crpl(node);
> +	if (net_msg_check_replay_cache(net, src, crpl, seq, iv_index))
>  		return false;
>  
> +	clear_text = l_malloc(size);
>  	forward.data = clear_text;
>  
>  	/*
> @@ -995,16 +997,6 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
>  		goto done;
>  	}
>  
> -	/* print_packet("Clr Rx (pre-cache-check)", clear_text, size - 4); */
> -
> -	crpl = node_get_crpl(node);
> -
> -	if (net_msg_in_replay_cache(net, (uint16_t) decrypt_idx, src,
> -				crpl, seq, iv_index)) {
> -		result = true;
> -		goto done;
> -	}
> -
>  	print_packet("Clr Rx", clear_text, size - (szmict ? 8 : 4));
>  
>  	forward.virt = decrypt_virt;
> @@ -1073,7 +1065,7 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
>  		 * Either the message has been processed internally or
>  		 * has been passed on to an external model.
>  		 */
> -		result = forward.has_dst | forward.done;
> +		result |= forward.has_dst | forward.done;
>  
>  		/* If the message was to unicast address, we are done */
>  		if (!is_subscription && ele_idx == i)
> @@ -1088,8 +1080,13 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0,
>  			break;
>  	}
>  
> +	/* If this message handlable by us, add to RPL */
> +	if (result)
> +		net_msg_add_replay_cache(net, src, seq, iv_index);
> +
>  done:
>  	l_free(clear_text);
> +
>  	return result;
>  }
>  
> diff --git a/mesh/net.c b/mesh/net.c
> index 19f3b87b7..d85df63da 100644
> --- a/mesh/net.c
> +++ b/mesh/net.c
> @@ -3759,9 +3759,8 @@ static bool clean_old_iv_index(void *a, void *b)
>  	return false;
>  }
>  
> -bool net_msg_in_replay_cache(struct mesh_net *net, uint16_t idx,
> -				uint16_t src, uint16_t crpl, uint32_t seq,
> -				uint32_t iv_index)
> +bool net_msg_check_replay_cache(struct mesh_net *net, uint16_t src,
> +				uint16_t crpl, uint32_t seq, uint32_t iv_index)
>  {
>  	struct mesh_rpl *rpe;
>  
> @@ -3782,49 +3781,50 @@ bool net_msg_in_replay_cache(struct mesh_net *net, uint16_t idx,
>  						L_UINT_TO_PTR(src));
>  
>  	if (rpe) {
> -		if (iv_index > rpe->iv_index) {
> -			rpe->seq = seq;
> -			rpe->iv_index = iv_index;
> -			rpl_put_entry(net->node, src, iv_index, seq);
> +		if (iv_index > rpe->iv_index)
>  			return false;
> -		}
> -
> -		if (seq < rpe->seq) {
> -			l_debug("Ignoring packet with lower sequence number");
> -			return true;
> -		}
>  
> -		if (seq == rpe->seq) {
> -			l_debug("Message already processed (duplicate)");
> +		/* return true if (iv_index | seq) too low */
> +		if (iv_index < rpe->iv_index || seq <= rpe->seq) {
> +			l_debug("Ignoring replayed packet");
>  			return true;
>  		}
> -
> -		rpe->seq = seq;
> -
> -		rpl_put_entry(net->node, src, iv_index, seq);
> -
> -		return false;
>  	}
>  
> -	l_debug("New Entry for %4.4x", src);
> -
> -	/* Replay Cache is fixed sized */
> -	if (l_queue_length(net->replay_cache) >= crpl) {
> +	/* SRC not in Replay Cache... see if there is space for it */
> +	else if (l_queue_length(net->replay_cache) >= crpl) {
>  		int ret = l_queue_foreach_remove(net->replay_cache,
>  				clean_old_iv_index, L_UINT_TO_PTR(iv_index));
>  
> +		/* Return true if no space could be freed */
>  		if (!ret)
>  			return true;
>  	}
>  
> -	if (!rpl_put_entry(net->node, src, iv_index, seq))
> -		return true;
> +	return false;
> +}
> +
> +void net_msg_add_replay_cache(struct mesh_net *net, uint16_t src, uint32_t seq,
> +							uint32_t iv_index)
> +{
> +	struct mesh_rpl *rpe;
> +
> +	if (!net || !net->node || !net->replay_cache)
> +		return;
> +
> +	rpe = l_queue_remove_if(net->replay_cache, match_replay_cache,
> +						L_UINT_TO_PTR(src));
> +
> +	if (!rpe) {
> +		l_debug("New Entry for %4.4x", src);
> +		rpe = l_new(struct mesh_rpl, 1);
> +		rpe->seq = src;
> +	}
>  
> -	rpe = l_new(struct mesh_rpl, 1);
> -	rpe->src = src;
>  	rpe->seq = seq;
>  	rpe->iv_index = iv_index;
> -	l_queue_push_head(net->replay_cache, rpe);
> +	rpl_put_entry(net->node, src, iv_index, seq);
>  
> -	return false;
> +	/* Optimize so that most recent conversations stay earliest in cache */
> +	l_queue_push_head(net->replay_cache, rpe);
>  }
> diff --git a/mesh/net.h b/mesh/net.h
> index ff0a9bb2b..6fedd69d7 100644
> --- a/mesh/net.h
> +++ b/mesh/net.h
> @@ -379,6 +379,7 @@ void mesh_net_set_prov(struct mesh_net *net, struct mesh_prov *prov);
>  uint32_t mesh_net_get_instant(struct mesh_net *net);
>  struct l_queue *mesh_net_get_friends(struct mesh_net *net);
>  struct l_queue *mesh_net_get_negotiations(struct mesh_net *net);
> -bool net_msg_in_replay_cache(struct mesh_net *net, uint16_t idx,
> -				uint16_t src, uint16_t crpl, uint32_t seq,
> -				uint32_t iv_index);
> +bool net_msg_check_replay_cache(struct mesh_net *net, uint16_t src,
> +				uint16_t crpl, uint32_t seq, uint32_t iv_index);
> +void net_msg_add_replay_cache(struct mesh_net *net, uint16_t src, uint32_t seq,
> +							uint32_t iv_index);




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux