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