1# $OpenBSD: rekey.sh,v 1.30 2024/08/28 12:08:26 djm Exp $ 2# Placed in the Public Domain. 3 4tid="rekey" 5 6LOG=${TEST_SSH_LOGFILE} 7COPY2=$OBJ/copy2 8 9rm -f ${LOG} 10cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak 11 12echo "Compression no" >> $OBJ/ssh_proxy 13echo "RekeyLimit 256k" >> $OBJ/ssh_proxy 14echo "KexAlgorithms curve25519-sha256" >> ssh_proxy 15 16# Test rekeying based on data volume only. 17# Arguments: rekeylimit, kex method, optional remaining opts are passed to ssh. 18ssh_data_rekeying() 19{ 20 _bytes=$1 ; shift 21 _kexopt=$1 ; shift 22 _opts="$@" 23 if test -z "$_bytes"; then 24 _bytes=32k 25 fi 26 if ! test -z "$_kexopt" ; then 27 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 28 echo "$_kexopt" >> $OBJ/sshd_proxy 29 _opts="$_opts -o$_kexopt" 30 fi 31 case "$_kexopt" in 32 MACs=*) 33 # default chacha20-poly1305 cipher has implicit MAC 34 _opts="$_opts -oCiphers=aes128-ctr" ;; 35 esac 36 trace bytes $_bytes kex $_kexopt opts $_opts 37 rm -f ${COPY} ${COPY2} ${LOG} 38 # Create data file just big enough to reach rekey threshold. 39 dd if=${DATA} of=${COPY} bs=$_bytes count=1 2>/dev/null 40 ${SSH} <${COPY} $_opts -vv \ 41 -oRekeyLimit=$_bytes -F $OBJ/ssh_proxy somehost "cat >${COPY2}" 42 if [ $? -ne 0 ]; then 43 fail "ssh failed ($@)" 44 fi 45 cmp ${COPY} ${COPY2} || fail "corrupted copy ($@)" 46 n=`grep 'NEWKEYS sent' ${LOG} | wc -l` 47 n=`expr $n - 1` 48 _want=`echo $_kexopt | cut -f2 -d=` 49 _got="" 50 case "$_kexopt" in 51 KexAlgorithms=*) 52 _got=`awk '/kex: algorithm: /{print $4}' ${LOG} | \ 53 tr -d '\r' | sort -u` ;; 54 Ciphers=*) 55 _got=`awk '/kex: client->server cipher:/{print $5}' ${LOG} | \ 56 tr -d '\r' | sort -u` ;; 57 MACs=*) 58 _got=`awk '/kex: client->server cipher:/{print $7}' ${LOG} | \ 59 tr -d '\r' | sort -u` ;; 60 esac 61 if [ "$_want" != "$_got" ]; then 62 fail "unexpected algorithm, want $_want, got $_got" 63 fi 64 trace "$n rekeying(s)" 65 if [ $n -lt 1 ]; then 66 fail "no rekeying occurred ($@)" 67 fi 68 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 69} 70 71increase_datafile_size 300 72 73opts="" 74 75# Filter out duplicate curve algo 76kexs=`${SSH} -Q kex | grep -v curve25519-sha256@libssh.org` 77ciphers=`${SSH} -Q cipher` 78macs=`${SSH} -Q mac` 79 80for i in $kexs; do 81 opts="$opts KexAlgorithms=$i" 82done 83for i in $ciphers; do 84 opts="$opts Ciphers=$i" 85done 86for i in $macs; do 87 opts="$opts MACs=$i" 88done 89 90for opt in $opts; do 91 verbose "client rekey $opt" 92 if ${SSH} -Q cipher-auth | sed 's/^/Ciphers=/' | \ 93 grep $opt >/dev/null; then 94 trace AEAD cipher, testing all KexAlgorithms 95 for kex in $kexs; do 96 ssh_data_rekeying "" "KexAlgorithms=$kex" "-o$opt" 97 done 98 else 99 ssh_data_rekeying "" "$opt" 100 fi 101done 102 103for s in 16 1k 128k 256k; do 104 verbose "client rekeylimit ${s}" 105 ssh_data_rekeying "$s" "" 106done 107 108for s in 5 10; do 109 verbose "client rekeylimit default ${s}" 110 rm -f ${COPY} ${LOG} 111 ${SSH} < ${DATA} -oRekeyLimit="default $s" -F \ 112 $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 10" 113 if [ $? -ne 0 ]; then 114 fail "ssh failed" 115 fi 116 cmp ${DATA} ${COPY} || fail "corrupted copy" 117 n=`grep 'NEWKEYS sent' ${LOG} | wc -l` 118 n=`expr $n - 1` 119 trace "$n rekeying(s)" 120 if [ $n -lt 1 ]; then 121 fail "no rekeying occurred" 122 fi 123done 124 125for s in 5 10; do 126 verbose "client rekeylimit default ${s} no data" 127 rm -f ${COPY} ${LOG} 128 ${SSH} -oRekeyLimit="default $s" -F \ 129 $OBJ/ssh_proxy somehost "sleep $s;sleep 10" 130 if [ $? -ne 0 ]; then 131 fail "ssh failed" 132 fi 133 n=`grep 'NEWKEYS sent' ${LOG} | wc -l` 134 n=`expr $n - 1` 135 trace "$n rekeying(s)" 136 if [ $n -lt 1 ]; then 137 fail "no rekeying occurred" 138 fi 139done 140 141for s in 16 1k 128k 256k; do 142 verbose "server rekeylimit ${s}" 143 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 144 echo "rekeylimit ${s}" >>$OBJ/sshd_proxy 145 rm -f ${COPY} ${COPY2} ${LOG} 146 dd if=${DATA} of=${COPY} bs=$s count=1 2>/dev/null 147 ${SSH} -F $OBJ/ssh_proxy somehost "cat ${COPY}" >${COPY2} 148 if [ $? -ne 0 ]; then 149 fail "ssh failed" 150 fi 151 cmp ${COPY} ${COPY2} || fail "corrupted copy" 152 n=`grep 'NEWKEYS sent' ${LOG} | wc -l` 153 n=`expr $n - 1` 154 trace "$n rekeying(s)" 155 if [ $n -lt 1 ]; then 156 fail "no rekeying occurred" 157 fi 158done 159 160for s in 5 10; do 161 verbose "server rekeylimit default ${s} no data" 162 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 163 echo "rekeylimit default ${s}" >>$OBJ/sshd_proxy 164 rm -f ${COPY} ${LOG} 165 ${SSH} -F $OBJ/ssh_proxy somehost "sleep $s;sleep 10" 166 if [ $? -ne 0 ]; then 167 fail "ssh failed" 168 fi 169 n=`grep 'NEWKEYS sent' ${LOG} | wc -l` 170 n=`expr $n - 1` 171 trace "$n rekeying(s)" 172 if [ $n -lt 1 ]; then 173 fail "no rekeying occurred" 174 fi 175done 176 177verbose "rekeylimit parsing: bytes" 178for size in 16 1k 1K 1m 1M 1g 1G 4G 8G; do 179 case $size in 180 16) bytes=16 ;; 181 1k|1K) bytes=1024 ;; 182 1m|1M) bytes=1048576 ;; 183 1g|1G) bytes=1073741824 ;; 184 4g|4G) bytes=4294967296 ;; 185 8g|8G) bytes=8589934592 ;; 186 esac 187 b=`${SSH} -G -o "rekeylimit $size" -F $OBJ/ssh_proxy host | \ 188 awk '/rekeylimit/{print $2}'` 189 if [ "$bytes" != "$b" ]; then 190 fatal "rekeylimit size: expected $bytes bytes got $b" 191 fi 192done 193 194verbose "rekeylimit parsing: time" 195for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do 196 case $time in 197 1) seconds=1 ;; 198 1m|1M) seconds=60 ;; 199 1h|1H) seconds=3600 ;; 200 1d|1D) seconds=86400 ;; 201 1w|1W) seconds=604800 ;; 202 esac 203 s=`${SSH} -G -o "rekeylimit default $time" -F $OBJ/ssh_proxy host | \ 204 awk '/rekeylimit/{print $3}'` 205 if [ "$seconds" != "$s" ]; then 206 fatal "rekeylimit time: expected $time seconds got $s" 207 fi 208done 209 210rm -f ${COPY} ${COPY2} ${DATA} 211