xref: /freebsd/crypto/openssh/regress/rekey.sh (revision 3d9fd9fcb432750f3716b28f6ccb0104cd9d351a)
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