wolfssl icon indicating copy to clipboard operation
wolfssl copied to clipboard

[Bug]: homebrew wolfSSL 8.5.4 fails on TLS_CHACHA20_POLY1305_SHA256

Open icing opened this issue 1 month ago • 2 comments

Contact Details

[email protected]

Version

wolfssl 8.5.4

Description

The homebrew delivered wolfSSL 8.5.4 fails when TLS_CHACHA20_POLY1305_SHA256 is being selected as cipher during the handshake on an ARM system. We see this in curl CI on macOS ARM jobs. The logged error is

SSL_connect failed with error -311: unknown type in record hdr

(Example: https://github.com/curl/curl/actions/runs/19582773452/job/56084526466)

AFAICT, the homebrew wolfssl formula has not really changed. One notable configure addition it does is --disable-armasm (see https://github.com/Homebrew/homebrew-core/blob/master/Formula/w/wolfssl.rb).

Building wolfssl 8.5.4 on my macOS Intel machine works fine. That is why I guess the ARM cipher handling somehow allows sending CHACHA20 in the ClientHello, but fails when parsing the ServerHello.

Reproduction steps

No response

Relevant log output


icing avatar Nov 23 '25 15:11 icing

Hi @icing,

I'm trying to reproduce this issue but having difficulties.

What is the test doing when failing? curl attempting to do TLS_CHACHA20_POLY1305 cipher suite on a Mac with ARM64 chip connecting to what server? Which implementation of SSL/TLS is the server using?

Outside of the CI loop is there something I can test against that represents the server that fails in the CI loop?

Sean

SparkiDev avatar Nov 26 '25 00:11 SparkiDev

Hi @SparkiDev,

I have no access to an ARM macOS machine to reproduce this locally. A failing test case can easily be run via:

curl> pytest -v -k "test_17_07 and TLSv1.2+3-CHACHA20SHA256-def"

is uses a local Apache httpd with OpenSSL something. This works for all other TLS backends and for previous wolfSSL versions like 5.8.2.

The test case set min SSL version to 1.2 and max version to 1.3. It sets the TLSv1.3 ciphers to TLS_CHACHA20_POLY1305_SHA256 and leaves the TLSv1.2 ciphers at default. The curl trace of a successful run is:

11:21:26.340044 [0-x] * Added one.http.curl.se:56498:127.0.0.1 to DNS cache
11:21:26.340209 [0-0] * Hostname one.http.curl.se was found in DNS cache
11:21:26.340372 [0-0] *   Trying 127.0.0.1:56498...
11:21:26.340687 [0-0] * Cipher selection: TLS_CHACHA20_POLY1305_SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-PSK-AES256-GCM-SHA384:DHE-PSK-AES128-GCM-SHA256:DHE-PSK-AES256-CBC-SHA384:DHE-PSK-AES128-CBC-SHA256:DHE-PSK-AES128-CCM:DHE-PSK-AES256-CCM:DHE-PSK-NULL-SHA384:DHE-PSK-NULL-SHA256:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-CCM-8:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES256-CCM-8:ECDHE-ECDSA-AES256-CCM8:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA256-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305-OLD:ECDHE-ECDSA-CHACHA20-POLY1305-OLD:DHE-RSA-CHACHA20-POLY1305-OLD:ADH-AES128-SHA:ADH-AES256-GCM-SHA384:ECDHE-ECDSA-NULL-SHA:ECDHE-PSK-NULL-SHA256:ECDHE-PSK-AES128-CBC-SHA256:ECDHE-PSK-AES128-GCM-SHA256:PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:WDM-NULL-SHA256
11:21:26.340922 [0-0] * ALPN: curl offers http/1.1
11:21:26.342650 [0-0] * successfully set certificate verify locations:
11:21:26.342781 [0-0] *  CAfile: /Users/sei/projects/curl/tests/http/gen/ca/ca.rsa2048.cert.pem
11:21:26.342907 [0-0] *  CApath: none
11:21:26.344610 [0-0] * ALPN: server accepted http/1.1
11:21:26.344738 [0-0] * SSL connection using TLSv1.3 / TLS13-CHACHA20-POLY1305-SHA256
11:21:26.344861 [0-0] * Established connection to one.http.curl.se (127.0.0.1 port 56498) from 127.0.0.1 port 56507 
11:21:26.344984 [0-0] * using HTTP/1.x
11:21:26.345118 [0-0] * sending last upload chunk of 106 bytes
11:21:26.345247 [0-0] * Curl_xfer_send(len=106, eos=1) -> 0, 106
11:21:26.345364 [0-0] > GET /curltest/sslinfo HTTP/1.1
11:21:26.345364 [0-0] > Host: one.http.curl.se:56498
11:21:26.345364 [0-0] > User-Agent: curl/8.18.0-DEV
11:21:26.345364 [0-0] > Accept: */*
11:21:26.345364 [0-0] > 
11:21:26.345979 [0-0] * Request completely sent off
11:21:26.346199 [0-0] < HTTP/1.1 200 OK
11:21:26.346367 [0-0] < Date: Wed, 26 Nov 2025 10:21:26 GMT
11:21:26.346495 [0-0] < Server: Apache/2.4.66-dev (Unix) OpenSSL/3.5.0
11:21:26.346616 [0-0] < Upgrade: h2
11:21:26.346738 [0-0] < Connection: Upgrade
11:21:26.346863 [0-0] < Transfer-Encoding: chunked
11:21:26.346987 [0-0] < Content-Type: application/json
11:21:26.347109 [0-0] < 
11:21:26.347230 [0-0] { [293 bytes data]
11:21:26.347438 [0-0] * Connection #0 to host one.http.curl.se:56498 left intact

With wolfSSL 5.8.4 from homebrew on ARM, this fails the handshake. The server response causes wolfSSL to fail with -311: unknown type in record hdr.

If there is anything else I can help you with, please let me know.

icing avatar Nov 26 '25 10:11 icing