Home | History | Annotate | Download | only in ipsec
      1 #!/bin/sh
      2 # Copyright (c) 2016 Red Hat Inc.,  All Rights Reserved.
      3 # Copyright (c) 2016 Oracle and/or its affiliates. All Rights Reserved.
      4 #
      5 # This program is free software; you can redistribute it and/or
      6 # modify it under the terms of the GNU General Public License as
      7 # published by the Free Software Foundation; either version 2 of
      8 # the License, or (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it would be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program; if not, see <http://www.gnu.org/licenses/>.
     17 #
     18 # Author: Hangbin Liu <haliu (at] redhat.com>
     19 #
     20 #######################################################################
     21 
     22 . test_net.sh
     23 
     24 # Authenticated encryption with associated data
     25 AEALGO="rfc4106_128"
     26 # Encryption algorithm
     27 EALGO="des3_ede"
     28 # Authentication algorithm
     29 AALGO="sha1"
     30 # Compression algorithm
     31 CALGO="deflate"
     32 
     33 while getopts "hl:m:p:s:S:k:A:e:a:c:6" opt; do
     34 	case "$opt" in
     35 	h)
     36 		echo "Usage:"
     37 		echo "h        help"
     38 		echo "l n      n is the number of test link when tests run"
     39 		echo "m x      x is ipsec mode, could be transport / tunnel"
     40 		echo "p x      x is ipsec protocol, could be ah / esp / ipcomp"
     41 		echo "s x      x is icmp messge size array"
     42 		echo "S n      n is IPsec SPI value"
     43 		echo "k x      key for vti interface"
     44 		echo "A x      Authenticated encryption with associated data algorithm"
     45 		echo "e x      Encryption algorithm"
     46 		echo "a x      Authentication algorithm"
     47 		echo "c x      Compression algorithm"
     48 		echo "6        run over IPv6"
     49 		exit 0
     50 	;;
     51 	l) LINK_NUM=$OPTARG ;;
     52 	m) IPSEC_MODE=$OPTARG ;;
     53 	p) IPSEC_PROTO=$OPTARG ;;
     54 	s) IPSEC_SIZE_ARRAY="$OPTARG" ;;
     55 	S) SPI=$OPTARG ;;
     56 	k) VTI_KEY=$OPTARG ;;
     57 	A) AEALGO=$OPTARG ;;
     58 	e) EALGO=$OPTARG ;;
     59 	a) AALGO=$OPTARG ;;
     60 	c) CALGO=$OPTARG ;;
     61 	6) # skip, test_net library already processed it
     62 	;;
     63 	*) tst_brkm TBROK "unknown option: $opt" ;;
     64 	esac
     65 done
     66 
     67 get_key()
     68 {
     69 	local bits=$1
     70 	local xdg_num=$(( $bits / 4 ))
     71 	echo "0x$(tr -dc "[:xdigit:]" < /dev/urandom | head -c$xdg_num)"
     72 }
     73 
     74 case $AEALGO in
     75 rfc4106_128|rfc4543_128) AEALGO_KEY=$(get_key 160) ;;
     76 rfc4106_192|rfc4543_192) AEALGO_KEY=$(get_key 224) ;;
     77 rfc4106_256|rfc4543_256) AEALGO_KEY=$(get_key 288) ;;
     78 rfc4309_128) AEALGO_KEY=$(get_key 152) ;;
     79 rfc4309_192) AEALGO_KEY=$(get_key 216) ;;
     80 rfc4309_256) AEALGO_KEY=$(get_key 280) ;;
     81 esac
     82 
     83 case $EALGO in
     84 des) EALGO_KEY=$(get_key 64) ;;
     85 des3_ede) EALGO_KEY=$(get_key 192) ;;
     86 cast5) EALGO_KEY=$(get_key 128) ;;
     87 blowfish) EALGO_KEY=$(get_key 448) ;;
     88 aes|twofish|camellia|serpent) EALGO_KEY=$(get_key 256) ;;
     89 *) tst_brkm TBROK "unknown enc alg: $EALGO" ;;
     90 esac
     91 
     92 case $AALGO in
     93 sha1|rmd160) AALGO_KEY=$(get_key 160) ;;
     94 sha256) AALGO_KEY=$(get_key 256) ;;
     95 sha384) AALGO_KEY=$(get_key 384) ;;
     96 sha512) AALGO_KEY=$(get_key 512) ;;
     97 *) tst_brkm TBROK "unknown auth alg: $AALGO" ;;
     98 esac
     99 
    100 SPI=${SPI:-1000}
    101 VTI_KEY=${VTI_KEY:-10}
    102 cleanup_vti=
    103 ALG=
    104 ALGR=
    105 
    106 # tst_ipsec_cleanup: flush ipsec state and policy rules
    107 tst_ipsec_cleanup()
    108 {
    109 	ip xfrm state flush
    110 	ip xfrm policy flush
    111 	tst_rhost_run -c "ip xfrm state flush && ip xfrm policy flush"
    112 
    113 	if [ -n "$cleanup_vti" ]; then
    114 		ip li del $cleanup_vti 2>/dev/null
    115 		tst_rhost_run -c "ip li del $cleanup_vti 2>/dev/null"
    116 	fi
    117 }
    118 
    119 ipsec_set_algoline()
    120 {
    121 	case $IPSEC_PROTO in
    122 	ah)
    123 		ALG='auth hmac('$AALGO') '$AALGO_KEY
    124 		ALGR='auth hmac\('$AALGO'\) '$AALGO_KEY
    125 		;;
    126 	esp)
    127 		ALG="enc $EALGO $EALGO_KEY auth "'hmac('$AALGO') '$AALGO_KEY
    128 		ALGR="enc $EALGO $EALGO_KEY auth "'hmac\('$AALGO'\) '$AALGO_KEY
    129 		;;
    130 	esp_aead)
    131 		case $AEALGO in
    132 		rfc4106_128|rfc4106_192|rfc4106_256)
    133 			ALG="aead "'rfc4106(gcm(aes))'" $AEALGO_KEY 128"
    134 			ALGR="aead "'rfc4106\(gcm\(aes\)\)'" $AEALGO_KEY 128"
    135 			;;
    136 		rfc4309_128|rfc4309_192|rfc4309_256)
    137 			ALG="aead "'rfc4309(ccm(aes))'" $AEALGO_KEY 128"
    138 			ALGR="aead "'rfc4309\(ccm\(aes\)\)'" $AEALGO_KEY 128"
    139 			;;
    140 		rfc4543_128|rfc4543_192|rfc4543_256)
    141 			ALG="aead "'rfc4543(gcm(aes))'" $AEALGO_KEY 128"
    142 			ALGR="aead "'rfc4543\(gcm\(aes\)\)'" $AEALGO_KEY 128"
    143 			;;
    144 		esac
    145 		;;
    146 	comp)
    147 		ALG="comp $CALGO"
    148 		ALGR=$ALG
    149 		;;
    150 	*)
    151 		tst_brkm TCONF "tst_ipsec protocol mismatch"
    152 		;;
    153 	esac
    154 }
    155 
    156 # tst_ipsec target src_addr dst_addr: config ipsec
    157 #
    158 # target: target of the configuration host ( lhost / rhost )
    159 # src_addr: source IP address
    160 # dst_addr: destination IP address
    161 tst_ipsec()
    162 {
    163 	if [ $# -ne 3 ]; then
    164 		tst_brkm TCONF "tst_ipsec parameter mismatch"
    165 	fi
    166 
    167 	local target=$1
    168 	local src=$2
    169 	local dst=$3
    170 	local mode=$IPSEC_MODE
    171 	local p="proto $IPSEC_PROTO"
    172 	[ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp"
    173 
    174 	ipsec_set_algoline
    175 
    176 	if [ $target = lhost ]; then
    177 		local spi_1="0x$SPI"
    178 		local spi_2="0x$(( $SPI + 1 ))"
    179 		ROD ip xfrm state add src $src dst $dst spi $spi_1 \
    180 			$p $ALG mode $mode sel src $src dst $dst
    181 		ROD ip xfrm state add src $dst dst $src spi $spi_2 \
    182 			$p $ALG mode $mode sel src $dst dst $src
    183 
    184 		ROD ip xfrm policy add src $src dst $dst dir out tmpl src $src \
    185 			dst $dst $p mode $mode
    186 		ROD ip xfrm policy add src $dst dst $src dir in tmpl src $dst \
    187 			dst $src $p mode $mode level use
    188 	elif [ $target = rhost ]; then
    189 		local spi_1="0x$(( $SPI + 1 ))"
    190 		local spi_2="0x$SPI"
    191 		tst_rhost_run -s -c "ip xfrm state add src $src dst $dst \
    192 			spi $spi_1 $p $ALGR mode $mode sel src $src dst $dst"
    193 		tst_rhost_run -s -c "ip xfrm state add src $dst dst $src \
    194 			spi $spi_2 $p $ALGR mode $mode sel src $dst dst $src"
    195 
    196 		tst_rhost_run -s -c "ip xfrm policy add src $src dst $dst \
    197 			dir out tmpl src $src dst $dst $p mode $mode"
    198 		tst_rhost_run -s -c "ip xfrm policy add src $dst dst $src dir \
    199 			in tmpl src $dst dst $src $p mode $mode level use"
    200 	fi
    201 }
    202 
    203 # tst_ipsec_vti target src_addr dst_addr vti_name
    204 #
    205 # target: target of the configuration host ( lhost / rhost )
    206 # src_addr: source IP address
    207 # dst_addr: destination IP address
    208 # vti_name: name of vti interface
    209 tst_ipsec_vti()
    210 {
    211 	if [ $# -ne 4 ]; then
    212 		tst_brkm TCONF "tst_ipsec_vti parameter mismatch"
    213 	fi
    214 
    215 	local target=$1
    216 	local src=$2
    217 	local dst=$3
    218 	local vti=$4
    219 	local m="mode $IPSEC_MODE"
    220 	local p="proto $IPSEC_PROTO"
    221 	[ "$IPSEC_PROTO" = "esp_aead" ] && p="proto esp"
    222 
    223 	local key="key $VTI_KEY"
    224 	local mrk="mark $VTI_KEY"
    225 	local type="type vti$TST_IPV6"
    226 
    227 	ip li add type vti help 2>&1 | grep -q vti || \
    228 		tst_brkm TCONF "iproute doesn't support 'vti'"
    229 
    230 	ipsec_set_algoline
    231 
    232 	local o_dir="src $src dst $dst"
    233 	local i_dir="src $dst dst $src"
    234 	local ipx="ip -${TST_IPV6:-4} xf"
    235 
    236 	cleanup_vti=$vti
    237 
    238 	if [ $target = lhost ]; then
    239 		ROD ip li add $vti $type local $src remote $dst $key
    240 		ROD ip li set $vti up
    241 
    242 		local spi_1="spi 0x$SPI"
    243 		local spi_2="spi 0x$(( $SPI + 1 ))"
    244 		ROD $ipx st add $o_dir $p $spi_1 $ALG $m
    245 		ROD $ipx st add $i_dir $p $spi_2 $ALG $m
    246 		ROD $ipx po add dir out tmpl $o_dir $p $m $mrk
    247 		ROD $ipx po add dir in tmpl $i_dir $p $m $mrk
    248 	elif [ $target = rhost ]; then
    249 		tst_rhost_run -s -c \
    250 			"ip li add $vti $type local $src remote $dst $key"
    251 		tst_rhost_run -s -c "ip li set $vti up"
    252 
    253 		local spi_1="spi 0x$(( $SPI + 1 ))"
    254 		local spi_2="spi 0x$SPI"
    255 		tst_rhost_run -s -c "$ipx st add $o_dir $p $spi_1 $ALGR $m"
    256 		tst_rhost_run -s -c "$ipx st add $i_dir $p $spi_2 $ALGR $m"
    257 		tst_rhost_run -s -c "$ipx po add dir out tmpl $o_dir $p $m $mrk"
    258 		tst_rhost_run -s -c "$ipx po add dir in tmpl $i_dir $p $m $mrk"
    259 	fi
    260 }
    261