Home | History | Annotate | Download | only in ipsec
      1 #!/bin/sh
      2 # SPDX-License-Identifier: GPL-2.0-or-later
      3 # Copyright (c) 2018 Petr Vorel <pvorel (at] suse.cz>
      4 # Copyright (c) 2016 Red Hat Inc.,  All Rights Reserved.
      5 # Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved.
      6 # Author: Hangbin Liu <haliu (at] redhat.com>
      7 
      8 # Authenticated encryption with associated data
      9 AEALGO="rfc4106_128"
     10 # Encryption algorithm
     11 EALGO="des3_ede"
     12 # Authentication algorithm
     13 AALGO="sha1"
     14 # Compression algorithm
     15 CALGO="deflate"
     16 
     17 IPSEC_REQUESTS="500"
     18 
     19 ipsec_lib_usage()
     20 {
     21 	echo "l n     n is the number of test link when tests run"
     22 	echo "m x     x is ipsec mode, could be transport / tunnel"
     23 	echo "p x     x is ipsec protocol, could be ah / esp / comp"
     24 	echo "s x     x is icmp message size array"
     25 	echo "S n     n is IPsec SPI value"
     26 	echo "k x     key for vti interface"
     27 	echo "A x     Authenticated encryption with associated data algorithm"
     28 	echo "e x     Encryption algorithm"
     29 	echo "a x     Authentication algorithm"
     30 	echo "c x     Compression algorithm"
     31 	echo "r x     Num of requests, PING_MAX or netstress' '-r' opt"
     32 }
     33 
     34 ipsec_lib_parse_args()
     35 {
     36 	case "$1" in
     37 	l) LINK_NUM=$2;;
     38 	m) IPSEC_MODE=$2;;
     39 	p) IPSEC_PROTO=$2;;
     40 	s) TST_TEST_DATA="$2"; TST_TEST_DATA_IFS=":";;
     41 	S) SPI=$2;;
     42 	k) VTI_KEY=$2;;
     43 	A) AEALGO=$2;;
     44 	e) EALGO=$2;;
     45 	a) AALGO=$2;;
     46 	c) CALGO=$2;;
     47 	r) IPSEC_REQUESTS="$2";;
     48 	esac
     49 }
     50 
     51 ipsec_lib_setup()
     52 {
     53 	case $AEALGO in
     54 	rfc4106_128|rfc4543_128) AEALGO_KEY=$(get_key 160);;
     55 	rfc4106_192|rfc4543_192) AEALGO_KEY=$(get_key 224);;
     56 	rfc4106_256|rfc4543_256) AEALGO_KEY=$(get_key 288);;
     57 	rfc4309_128) AEALGO_KEY=$(get_key 152);;
     58 	rfc4309_192) AEALGO_KEY=$(get_key 216);;
     59 	rfc4309_256) AEALGO_KEY=$(get_key 280);;
     60 	esac
     61 
     62 	case $EALGO in
     63 	des) EALGO_KEY=$(get_key 64);;
     64 	des3_ede) EALGO_KEY=$(get_key 192);;
     65 	cast5) EALGO_KEY=$(get_key 128);;
     66 	blowfish) EALGO_KEY=$(get_key 448);;
     67 	aes|twofish|camellia|serpent) EALGO_KEY=$(get_key 256);;
     68 	*) tst_brk TBROK "unknown enc alg: $EALGO";;
     69 	esac
     70 
     71 	case $AALGO in
     72 	sha1|rmd160) AALGO_KEY=$(get_key 160);;
     73 	sha256) AALGO_KEY=$(get_key 256);;
     74 	sha384) AALGO_KEY=$(get_key 384);;
     75 	sha512) AALGO_KEY=$(get_key 512);;
     76 	*) tst_brk TBROK "unknown auth alg: $AALGO";;
     77 	esac
     78 
     79 	SPI=${SPI:-1000}
     80 	VTI_KEY=${VTI_KEY:-10}
     81 	cleanup_vti=
     82 	ALG=
     83 	ALGR=
     84 
     85 	if [ -n "$IPSEC_MODE" ]; then
     86 		tst_net_run "tst_check_drivers xfrm_user" || \
     87 			tst_brk TCONF "xfrm_user driver not available on lhost or rhost"
     88 		cleanup_xfrm=1
     89 	fi
     90 }
     91 
     92 TST_OPTS="l:m:p:s:S:k:A:e:a:c:r:"
     93 TST_PARSE_ARGS=ipsec_lib_parse_args
     94 TST_SETUP=${TST_SETUP:-ipsec_lib_setup}
     95 TST_USAGE=ipsec_lib_usage
     96 . tst_net.sh
     97 
     98 get_key()
     99 {
    100 	local bits=$1
    101 	local bytes=$(( $bits / 8))
    102 	echo "0x$(hexdump -vn $bytes -e '1/1 "%02x"' /dev/urandom)"
    103 }
    104 
    105 tst_ipsec_setup()
    106 {
    107 	ipsec_lib_setup
    108 	# Configure SAD/SPD
    109 	if [ -n "$IPSEC_MODE" -a -n "$IPSEC_PROTO" ]; then
    110 		tst_res TINFO "IPsec[$IPSEC_PROTO/$IPSEC_MODE]"
    111 		tst_ipsec lhost $(tst_ipaddr) $(tst_ipaddr rhost)
    112 		tst_ipsec rhost $(tst_ipaddr rhost) $(tst_ipaddr)
    113 	fi
    114 }
    115 
    116 # tst_ipsec_cleanup: flush ipsec state and policy rules
    117 tst_ipsec_cleanup()
    118 {
    119 	[ -z "$cleanup_xfrm" ] && return
    120 
    121 	ip xfrm state flush
    122 	ip xfrm policy flush
    123 	tst_rhost_run -c "ip xfrm state flush && ip xfrm policy flush"
    124 
    125 	if [ -n "$cleanup_vti" ]; then
    126 		ip li del $cleanup_vti 2>/dev/null
    127 		tst_rhost_run -c "ip li del $cleanup_vti 2>/dev/null"
    128 	fi
    129 }
    130 
    131 ipsec_set_algoline()
    132 {
    133 	case $IPSEC_PROTO in
    134 	ah)
    135 		ALG='auth hmac('$AALGO') '$AALGO_KEY
    136 		ALGR='auth hmac\('$AALGO'\) '$AALGO_KEY
    137 		;;
    138 	esp)
    139 		ALG="enc $EALGO $EALGO_KEY auth "'hmac('$AALGO') '$AALGO_KEY
    140 		ALGR="enc $EALGO $EALGO_KEY auth "'hmac\('$AALGO'\) '$AALGO_KEY
    141 		;;
    142 	esp_aead)
    143 		case $AEALGO in
    144 		rfc4106_128|rfc4106_192|rfc4106_256)
    145 			ALG="aead "'rfc4106(gcm(aes))'" $AEALGO_KEY 128"
    146 			ALGR="aead "'rfc4106\(gcm\(aes\)\)'" $AEALGO_KEY 128"
    147 			;;
    148 		rfc4309_128|rfc4309_192|rfc4309_256)
    149 			ALG="aead "'rfc4309(ccm(aes))'" $AEALGO_KEY 128"
    150 			ALGR="aead "'rfc4309\(ccm\(aes\)\)'" $AEALGO_KEY 128"
    151 			;;
    152 		rfc4543_128|rfc4543_192|rfc4543_256)
    153 			ALG="aead "'rfc4543(gcm(aes))'" $AEALGO_KEY 128"
    154 			ALGR="aead "'rfc4543\(gcm\(aes\)\)'" $AEALGO_KEY 128"
    155 			;;
    156 		esac
    157 		;;
    158 	comp)
    159 		ALG="comp $CALGO"
    160 		ALGR=$ALG
    161 		;;
    162 	*)
    163 		tst_brk TCONF "tst_ipsec protocol mismatch"
    164 		;;
    165 	esac
    166 }
    167 
    168 # tst_ipsec target src_addr dst_addr: config ipsec
    169 #
    170 # target: target of the configuration host ( lhost / rhost )
    171 # src_addr: source IP address
    172 # dst_addr: destination IP address
    173 tst_ipsec()
    174 {
    175 	if [ $# -ne 3 ]; then
    176 		tst_brk TCONF "tst_ipsec parameter mismatch"
    177 	fi
    178 
    179 	local target=$1
    180 	local src=$2
    181 	local dst=$3
    182 	local mode=$IPSEC_MODE
    183 	local p="proto $IPSEC_PROTO"
    184 	[ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp"
    185 
    186 	ipsec_set_algoline
    187 
    188 	if [ $target = lhost ]; then
    189 		local spi_1="0x$SPI"
    190 		local spi_2="0x$(( $SPI + 1 ))"
    191 		TST_RTNL_CHK ip xfrm state add src $src dst $dst spi $spi_1 \
    192 			$p $ALG mode $mode sel src $src dst $dst
    193 		ROD ip xfrm state add src $dst dst $src spi $spi_2 \
    194 			$p $ALG mode $mode sel src $dst dst $src
    195 
    196 		ROD ip xfrm policy add src $src dst $dst dir out tmpl src $src \
    197 			dst $dst $p mode $mode
    198 		ROD ip xfrm policy add src $dst dst $src dir in tmpl src $dst \
    199 			dst $src $p mode $mode level use
    200 	elif [ $target = rhost ]; then
    201 		local spi_1="0x$(( $SPI + 1 ))"
    202 		local spi_2="0x$SPI"
    203 		tst_rhost_run -s -c "ip xfrm state add src $src dst $dst \
    204 			spi $spi_1 $p $ALGR mode $mode sel src $src dst $dst"
    205 		tst_rhost_run -s -c "ip xfrm state add src $dst dst $src \
    206 			spi $spi_2 $p $ALGR mode $mode sel src $dst dst $src"
    207 
    208 		tst_rhost_run -s -c "ip xfrm policy add src $src dst $dst \
    209 			dir out tmpl src $src dst $dst $p mode $mode"
    210 		tst_rhost_run -s -c "ip xfrm policy add src $dst dst $src dir \
    211 			in tmpl src $dst dst $src $p mode $mode level use"
    212 	fi
    213 }
    214 
    215 # tst_ipsec_vti target src_addr dst_addr vti_name
    216 #
    217 # target: target of the configuration host ( lhost / rhost )
    218 # src_addr: source IP address
    219 # dst_addr: destination IP address
    220 # vti_name: name of vti interface
    221 tst_ipsec_vti()
    222 {
    223 	if [ $# -ne 4 ]; then
    224 		tst_brk TCONF "tst_ipsec_vti parameter mismatch"
    225 	fi
    226 
    227 	local target=$1
    228 	local src=$2
    229 	local dst=$3
    230 	local vti=$4
    231 	local m="mode $IPSEC_MODE"
    232 	local p="proto $IPSEC_PROTO"
    233 	[ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp"
    234 
    235 	local key="key $VTI_KEY"
    236 	local mrk="mark $VTI_KEY"
    237 	local type="type vti$TST_IPV6"
    238 	local d="dev $(tst_iface)"
    239 	local rd="dev $(tst_iface rhost)"
    240 
    241 	ip li add type vti help 2>&1 | grep -q vti || \
    242 		tst_brk TCONF "iproute doesn't support 'vti'"
    243 
    244 	ipsec_set_algoline
    245 
    246 	local o_dir="src $src dst $dst"
    247 	local i_dir="src $dst dst $src"
    248 	local ipx="ip -${TST_IPV6:-4} xf"
    249 
    250 	cleanup_vti=$vti
    251 
    252 	if [ $target = lhost ]; then
    253 		TST_RTNL_CHK ip li add $vti $type local $src remote $dst $key $d
    254 		ROD ip li set $vti up
    255 
    256 		local spi_1="spi 0x$SPI"
    257 		local spi_2="spi 0x$(( $SPI + 1 ))"
    258 		TST_RTNL_CHK $ipx st add $o_dir $p $spi_1 $ALG $m
    259 		ROD $ipx st add $i_dir $p $spi_2 $ALG $m
    260 		ROD $ipx po add dir out tmpl $o_dir $p $m $mrk
    261 		ROD $ipx po add dir in tmpl $i_dir $p $m $mrk
    262 	elif [ $target = rhost ]; then
    263 		tst_rhost_run -s -c \
    264 			"ip li add $vti $type local $src remote $dst $key $rd"
    265 		tst_rhost_run -s -c "ip li set $vti up"
    266 
    267 		local spi_1="spi 0x$(( $SPI + 1 ))"
    268 		local spi_2="spi 0x$SPI"
    269 		tst_rhost_run -s -c "$ipx st add $o_dir $p $spi_1 $ALGR $m"
    270 		tst_rhost_run -s -c "$ipx st add $i_dir $p $spi_2 $ALGR $m"
    271 		tst_rhost_run -s -c "$ipx po add dir out tmpl $o_dir $p $m $mrk"
    272 		tst_rhost_run -s -c "$ipx po add dir in tmpl $i_dir $p $m $mrk"
    273 	fi
    274 }
    275 
    276 # Setup vti/vti6 interface for IPsec tunneling
    277 # The function sets variables:
    278 #  * tst_vti - vti interface name,
    279 #  * ip_loc_tun - local IP address on vti interface
    280 #  * ip_rmt_tun - remote IP address
    281 tst_ipsec_setup_vti()
    282 {
    283 	ipsec_lib_setup
    284 
    285 	if_loc=$(tst_iface)
    286 	if_rmt=$(tst_iface rhost)
    287 
    288 	ip_loc=$(tst_ipaddr)
    289 	ip_rmt=$(tst_ipaddr rhost)
    290 
    291 	tst_vti="ltp_vti0"
    292 
    293 	tst_res TINFO "Test vti$TST_IPV6 + IPsec[$IPSEC_PROTO/$IPSEC_MODE]"
    294 
    295 	tst_ipsec_vti lhost $ip_loc $ip_rmt $tst_vti
    296 	tst_ipsec_vti rhost $ip_rmt $ip_loc $tst_vti
    297 
    298 	local mask=
    299 	if [ "$TST_IPV6" ]; then
    300 		ip_loc_tun="${IPV6_NET32_UNUSED}::1";
    301 		ip_rmt_tun="${IPV6_NET32_UNUSED}::2";
    302 		mask=64
    303 		ROD ip -6 route add ${IPV6_NET32_UNUSED}::/$mask dev $tst_vti
    304 	else
    305 		ip_loc_tun="${IPV4_NET16_UNUSED}.1.1";
    306 		ip_rmt_tun="${IPV4_NET16_UNUSED}.1.2";
    307 		mask=30
    308 		ROD ip route add ${IPV4_NET16_UNUSED}.1.0/$mask dev $tst_vti
    309 	fi
    310 
    311 	tst_res TINFO "Add IPs to vti tunnel, " \
    312 		       "loc: $ip_loc_tun/$mask, rmt: $ip_rmt_tun/$mask"
    313 
    314 	ROD ip a add $ip_loc_tun/$mask dev $tst_vti nodad
    315 	tst_rhost_run -s -c "ip a add $ip_rmt_tun/$mask dev $tst_vti"
    316 }
    317