java-topology/whitepaper/outreach/wolfssl.md

95 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WolfSSL — CWE-407 Disclosure Brief
**Project:** WolfSSL
**Disclosure date:** 2026-03-27
**Severity:** HIGH
**Speedup:** varies with S×C
**Status:** PATCHED
---
## Finding
WolfSSL's ALPN negotiation in `src/tls.c` performs an O(S×C) double loop when matching server and client ALPN protocol names. `TLSX_ALPN_GetRequest()` iterates over S server-configured ALPN names in an outer loop and for each performs an inner `while` scan over C client-offered names. This executes on every TLS handshake that includes the ALPN extension, which is mandatory for HTTP/2 and common for gRPC.
## The Defect(s)
| ID | Location | Pattern | Complexity |
|----|----------|---------|------------|
| wolfssl-0001 | `src/tls.c` | `TLSX_ALPN_GetRequest()` outer for over S server names × inner while over C client names | O(S×C) per handshake |
## Complexity Proof
Let S = number of ALPN protocol names configured on the server, C = number of ALPN protocol names offered by the client, L = average protocol name byte length.
`TLSX_ALPN_GetRequest()` iterates the server's ALPN list in an outer loop. For each server name, it traverses the linked list of client names in an inner `while` loop, performing a string comparison (O(L)) at each step:
```
For server_name_1: scan C client names → up to C×L byte comparisons
For server_name_2: scan C client names → up to C×L byte comparisons
...
For server_name_S: scan C client names → up to C×L byte comparisons
Total: S × C × L byte comparisons per handshake
```
Pre-building a hash set of client ALPN names (keyed by interned string pointer or FNV hash) before the outer loop reduces the inner scan to O(1) per server name:
```
Fixed: build hash set O(C×L) + outer loop S × O(1) = O(C×L + S)
Speedup: S× over the inner scan; net speedup depends on S/C ratio
```
For S = 6 server protocols and C = 8 client protocols with L = 15 bytes average (e.g., "h2", "http/1.1", "grpc"), the defective path performs 720 byte comparisons; the fixed path performs 90 (set build) + 6 (lookups) = 96.
## Impact
Every WolfSSL TLS connection that includes ALPN extension processing is affected. WolfSSL is widely deployed in embedded systems, IoT devices, automotive ECUs, and RTOS environments. These resource-constrained targets have no CPU budget to spare for quadratic handshake work. High-connection-rate WolfSSL deployments (embedded HTTP/2 servers, MQTT brokers, industrial IoT gateways) processing many simultaneous TLS handshakes are most affected. The defect compounds when both S and C are large (which occurs in environments advertising backward compatibility for multiple protocol generations).
## The Fix
Before the outer server-name loop in `TLSX_ALPN_GetRequest()`, iterate the client ALPN list once to build a hash set of client names. Replace the inner `while` scan with an O(1) hash set lookup for each server name.
## Patch
```diff
- int TLSX_ALPN_GetRequest(TLSX* extensions, const void** data, word16* size) {
- ALPN* server_alpn = (ALPN*)TLSX_Find(extensions, TLSX_APPLICATION_LAYER_PROTOCOL)->data;
- ALPN* client_alpn = ...;
- while (server_alpn) {
- ALPN* ca = client_alpn;
- while (ca) {
- if (XSTRNCMP(server_alpn->protocol_name, ca->protocol_name,
- server_alpn->protocol_nameSz) == 0) {
- /* match found */
- }
- ca = ca->next;
- }
- server_alpn = server_alpn->next;
- }
- }
+ int TLSX_ALPN_GetRequest(TLSX* extensions, const void** data, word16* size) {
+ /* build hash set of client ALPN names */
+ AlpnHashSet client_set;
+ AlpnHashSet_Init(&client_set);
+ ALPN* ca = client_alpn;
+ while (ca) { AlpnHashSet_Add(&client_set, ca->protocol_name, ca->protocol_nameSz); ca = ca->next; }
+
+ ALPN* server_alpn = ...;
+ while (server_alpn) {
+ if (AlpnHashSet_Contains(&client_set, server_alpn->protocol_name,
+ server_alpn->protocol_nameSz)) {
+ /* match found */
+ }
+ server_alpn = server_alpn->next;
+ }
+ AlpnHashSet_Free(&client_set);
+ }
```
## What We Ask
Please review, apply, and coordinate a 90-day disclosure window before public release. Reply to security@undefect.com.
---
*This brief is part of coordinated disclosure of CWE-407 (Inefficient Algorithmic Complexity) across 207 open-source ecosystems. Full report: https://undefect.com*