1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (c) 2018 Petr Vorel <pvorel@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@redhat.com> 7 8# Authenticated encryption with associated data 9AEALGO="rfc4106_128" 10# Encryption algorithm 11EALGO="des3_ede" 12# Authentication algorithm 13AALGO="sha1" 14# Compression algorithm 15CALGO="deflate" 16 17IPSEC_REQUESTS="500" 18 19ipsec_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 34ipsec_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 51ipsec_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 -q "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 92TST_OPTS="l:m:p:s:S:k:A:e:a:c:r:" 93TST_PARSE_ARGS=ipsec_lib_parse_args 94TST_SETUP=${TST_SETUP:-ipsec_lib_setup} 95TST_USAGE=ipsec_lib_usage 96. tst_net.sh 97 98get_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 105tst_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 117tst_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 link del $cleanup_vti 2>/dev/null 127 tst_rhost_run -c "ip link del $cleanup_vti 2>/dev/null" 128 fi 129} 130 131ipsec_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 173tst_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 221tst_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 link 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_IPVER xf" 249 250 cleanup_vti=$vti 251 252 if [ $target = lhost ]; then 253 TST_RTNL_CHK ip link add $vti $type local $src remote $dst $key $d 254 ROD ip link 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 link add $vti $type local $src remote $dst $key $rd" 265 tst_rhost_run -s -c "ip link 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 281tst_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_net_run -q "tst_check_drivers ip${TST_IPV6}_vti" || \ 296 tst_brk TCONF "ip${TST_IPV6}_vti driver not available on lhost or rhost" 297 298 tst_ipsec_vti lhost $ip_loc $ip_rmt $tst_vti 299 tst_ipsec_vti rhost $ip_rmt $ip_loc $tst_vti 300 301 local mask address_opt 302 if [ "$TST_IPV6" ]; then 303 ip_loc_tun="${IPV6_NET32_UNUSED}::1"; 304 ip_rmt_tun="${IPV6_NET32_UNUSED}::2"; 305 mask=64 306 address_opt=nodad 307 ROD ip -6 route add ${IPV6_NET32_UNUSED}::/$mask dev $tst_vti 308 else 309 ip_loc_tun="${IPV4_NET16_UNUSED}.1.1"; 310 ip_rmt_tun="${IPV4_NET16_UNUSED}.1.2"; 311 mask=30 312 ROD ip route add ${IPV4_NET16_UNUSED}.1.0/$mask dev $tst_vti 313 fi 314 315 tst_res TINFO "Add IPs to vti tunnel, " \ 316 "loc: $ip_loc_tun/$mask, rmt: $ip_rmt_tun/$mask" 317 318 ROD ip addr add $ip_loc_tun/$mask dev $tst_vti $address_opt 319 tst_rhost_run -s -c "ip addr add $ip_rmt_tun/$mask dev $tst_vti" 320} 321