ipsec_lib.sh 8.3 KB

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