Skip to content

Commit e2accb6

Browse files
author
David Cooper
committed
ChaCha20 decryption
Decryption is TLS 1.3 handshakes is very slow if the response is encrypted using ChaCha20 and the $OPENSSL enc command does not support ChaCha20. This commit mitigates that problem by using $OPENSSL2 for ChaCha20 decryption if such decryption is needed and $OPENSSL does not support it. This commit also changes testssl.sh to make use of $OPENSSL2 for AES-GCM decryption, when $OPENSSL2 supports it, but $OPENSSL does not. However, this change is not as important. Implementing AES-GCM in Bash using $OPENSSL for AES ECB operations isn't nearly as slow as fully implementing ChaCha20 in Bash.
1 parent a348839 commit e2accb6

1 file changed

Lines changed: 47 additions & 16 deletions

File tree

testssl.sh

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ TLS_DATA_FILE="" # mandatory file for socket-based handsh
247247
OPENSSL="" # ~/bin/openssl.$(uname).$(uname -m) if you run this from GitHub. Linux otherwise probably /usr/bin/openssl
248248
OPENSSL2=${OPENSSL2:-/usr/bin/openssl} # This will be openssl version >=1.1.1 (auto determined) as opposed to openssl-bad (OPENSSL)
249249
OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this will be set to true
250+
OPENSSL2_HAS_CHACHA20=false
251+
OPENSSL2_HAS_AES128_GCM=false
252+
OPENSSL2_HAS_AES256_GCM=false
250253
OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # If you don't want automagically switch from $OPENSSL to $OPENSSL2 for TLS 1.3-only hosts, set this to false
251254
OPENSSL_LOCATION=""
252255
OPENSSL_NOTIMEOUT="" # Needed for renegotiation tests
@@ -13117,6 +13120,11 @@ chacha20() {
1311713120
$OPENSSL enc -chacha20 -K "$key" -iv "01000000$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
1311813121
tm_out "$(strip_spaces "$plaintext")"
1311913122
return 0
13123+
elif "$OPENSSL2_HAS_CHACHA20"; then
13124+
plaintext="$(hex2binary "$ciphertext" | \
13125+
$OPENSSL2 enc -chacha20 -K "$key" -iv "01000000$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
13126+
tm_out "$(strip_spaces "$plaintext")"
13127+
return 0
1312013128
fi
1312113129

1312213130
ciphertext_len=${#ciphertext}
@@ -13808,11 +13816,21 @@ gcm-decrypt() {
1380813816
$OPENSSL enc -aes-128-gcm -K "$key" -iv "$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
1380913817
tm_out "$(strip_spaces "$plaintext")"
1381013818
return 0
13819+
elif [[ "$cipher" == TLS_AES_128_GCM_SHA256 ]] && "$OPENSSL2_HAS_AES128_GCM" && ! "$compute_tag"; then
13820+
plaintext="$(hex2binary "$ciphertext" | \
13821+
$OPENSSL2 enc -aes-128-gcm -K "$key" -iv "$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
13822+
tm_out "$(strip_spaces "$plaintext")"
13823+
return 0
1381113824
elif [[ "$cipher" == TLS_AES_256_GCM_SHA384 ]] && "$HAS_AES256_GCM" && ! "$compute_tag"; then
1381213825
plaintext="$(hex2binary "$ciphertext" | \
1381313826
$OPENSSL enc -aes-256-gcm -K "$key" -iv "$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
1381413827
tm_out "$(strip_spaces "$plaintext")"
1381513828
return 0
13829+
elif [[ "$cipher" == TLS_AES_256_GCM_SHA384 ]] && "$OPENSSL2_HAS_AES256_GCM" && ! "$compute_tag"; then
13830+
plaintext="$(hex2binary "$ciphertext" | \
13831+
$OPENSSL2 enc -aes-256-gcm -K "$key" -iv "$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')"
13832+
tm_out "$(strip_spaces "$plaintext")"
13833+
return 0
1381613834
fi
1381713835

1381813836
case "$cipher" in
@@ -20695,32 +20713,45 @@ find_openssl_binary() {
2069520713

2069620714
grep -qe '-enable_pha' $s_client_has && HAS_ENABLE_PHA=true
2069720715

20698-
# Now check whether the standard $OPENSSL has Unix-domain socket and xmpp-server support. If
20699-
# not check /usr/bin/openssl -- if available. This is more a kludge which we shouldn't use for
20700-
# every openssl feature. At some point we need to decide which with openssl version we go.
20701-
# We also check, whether there's /usr/bin/openssl which has TLS 1.3
20702-
if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ ! $OSSL_VER =~ 1.1.1 ]] && [[ $OSSL_VER_MAJOR -lt 3 ]]; then
20703-
if [[ -x $OPENSSL2 ]]; then
20716+
$OPENSSL enc -chacha20 -K 12345678901234567890123456789012 -iv 01000000123456789012345678901234 > /dev/null 2> /dev/null <<< "test"
20717+
[[ $? -eq 0 ]] && HAS_CHACHA20=true
20718+
20719+
$OPENSSL enc -aes-128-gcm -K 0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test"
20720+
[[ $? -eq 0 ]] && HAS_AES128_GCM=true
20721+
20722+
$OPENSSL enc -aes-256-gcm -K 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test"
20723+
[[ $? -eq 0 ]] && HAS_AES256_GCM=true
20724+
20725+
if [[ $OPENSSL2 != $OPENSSL ]] && [[ -x $OPENSSL2 ]]; then
20726+
if ! "$HAS_CHACHA20"; then
20727+
$OPENSSL2 enc -chacha20 -K 12345678901234567890123456789012 -iv 01000000123456789012345678901234 > /dev/null 2> /dev/null <<< "test"
20728+
[[ $? -eq 0 ]] && OPENSSL2_HAS_CHACHA20=true
20729+
fi
20730+
if ! "$HAS_AES128_GCM"; then
20731+
$OPENSSL2 enc -aes-128-gcm -K 0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test"
20732+
[[ $? -eq 0 ]] && OPENSSL2_HAS_AES128_GCM=true
20733+
fi
20734+
if ! "$HAS_AES256_GCM"; then
20735+
$OPENSSL2 enc -aes-256-gcm -K 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test"
20736+
[[ $? -eq 0 ]] && OPENSSL2_HAS_AES256_GCM=true
20737+
fi
20738+
20739+
# Now check whether the standard $OPENSSL has Unix-domain socket and xmpp-server support. If
20740+
# not check $OPENSSL2 -- if available. This is more a kludge which we shouldn't use for
20741+
# every openssl feature. At some point we need to decide which with openssl version we go.
20742+
# We also check, whether there's $OPENSSL2 which has TLS 1.3
20743+
if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ ! $OSSL_VER =~ 1.1.1 ]] && [[ $OSSL_VER_MAJOR -lt 3 ]]; then
2070420744
$OPENSSL2 s_client -help 2>$s_client_has2
2070520745
$OPENSSL2 s_client -starttls foo 2>$s_client_starttls_has2
2070620746
grep -q 'Unix-domain socket' $s_client_has2 && HAS_UDS2=true
2070720747
grep -q 'xmpp-server' $s_client_starttls_has2 && HAS_XMPP_SERVER2=true
2070820748
# Likely we don't need the following second check here, see 6 lines above
20709-
if grep -wq 'tls1_3' $s_client_has2 && [[ $OPENSSL != /usr/bin/openssl ]]; then
20749+
if grep -wq 'tls1_3' $s_client_has2; then
2071020750
OPENSSL2_HAS_TLS_1_3=true
2071120751
fi
2071220752
fi
2071320753
fi
2071420754

20715-
$OPENSSL enc -chacha20 -K 12345678901234567890123456789012 -iv 01000000123456789012345678901234 > /dev/null 2> /dev/null <<< "test"
20716-
[[ $? -eq 0 ]] && HAS_CHACHA20=true
20717-
20718-
$OPENSSL enc -aes-128-gcm -K 0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test"
20719-
[[ $? -eq 0 ]] && HAS_AES128_GCM=true
20720-
20721-
$OPENSSL enc -aes-256-gcm -K 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test"
20722-
[[ $? -eq 0 ]] && HAS_AES256_GCM=true
20723-
2072420755
[[ "$(echo -e "\x78\x9C\xAB\xCA\xC9\x4C\xE2\x02\x00\x06\x20\x01\xBC" | $OPENSSL zlib -d 2>/dev/null)" == zlib ]] && HAS_ZLIB=true
2072520756

2072620757
$OPENSSL verify -trusted_first </dev/null 2>&1 | grep -q '^usage' || TRUSTED1ST="-trusted_first"

0 commit comments

Comments
 (0)