Implementation Effort Analysis: 1024-byte TLS Fragment Limit
July 6, 2025 · View on GitHub
Last Updated: 2025-07-06
Status: Active
Change History
2025-07-06
- Initial analysis of implementation approaches for 1024-byte TLS fragment limit
- Evaluated effort and complexity of various solutions
- Provided cost-benefit analysis
Executive Summary
This document analyzes the effort required to implement SHIP's mandatory requirement that "a SHIP node SHALL ensure that the fragment length (TLSPlaintext.length) of outgoing packets does not exceed 1024 bytes" in a Go-based implementation.
Requirement Clarification
The SHIP specification section 9.2 contains two distinct requirements:
- RFC 6066 support (SHOULD - optional)
- 1024-byte limit on outgoing TLS records (SHALL - mandatory)
The second requirement applies regardless of RFC 6066 negotiation and only affects outgoing data.
Implementation Approaches Analysis
Option 1: Fork crypto/tls
Effort: 2-4 weeks initial + ongoing maintenance
- Week 1: Study crypto/tls internals, understand record layer
- Week 2: Implement fragment size control in writeRecordLocked()
- Weeks 3-4: Testing, debugging, integration
Challenges:
- Must maintain fork synchronized with Go releases
- Security patches become your responsibility
- Risk of introducing vulnerabilities
- Certification concerns with modified TLS
Verdict: ❌ Not recommended
Option 2: Alternative TLS Library
Investigated Options:
- No pure-Go TLS library offers fragment control
- cloudflare/tls-tris discontinued
- Other implementations lack maturity
Effort: 1-2 months
- Find or build suitable implementation
- Add fragment control
- Extensive compatibility testing
Verdict: ❌ No viable options exist
Option 3: OpenSSL via CGO
Effort: 3-4 months (as documented in OpenSSL_Integration_Analysis.md)
- Replace entire TLS/WebSocket stack
- Cross-platform build complexity
- Ongoing maintenance burden
Implementation:
// With OpenSSL, it's one line:
SSL_CTX_set_max_send_fragment(ctx, 1024);
Verdict: ✅ Technically feasible but expensive
Option 4: TLS Proxy/Sidecar
Effort: 1-2 weeks
- Days 1-2: Set up stunnel with OpenSSL
- Days 3-5: Configure fragment limiting
- Week 2: Integration, testing, documentation
Architecture:
ship-go ←→ localhost:proxy ←→ TLS(1024) ←→ Remote
(plain WS) (fragment limited)
Example stunnel config:
[ship-tls]
client = yes
accept = 127.0.0.1:8080
connect = remote-host:443
maxfragment = 1024
Challenges:
- Additional process to manage
- Complex deployment
- Certificate management
- Debugging complexity
Verdict: ✅ Most pragmatic if required
Option 5: Application Layer Chunking
Why it doesn't work:
- Writing small chunks doesn't guarantee small TLS records
- crypto/tls may buffer and combine writes
- No control over record boundaries
Verdict: ❌ Cannot guarantee compliance
Performance Impact Analysis
Based on our testing with 8.7KB SPINE messages:
Standard TLS (16KB records):
- 1 TLS record
- ~29 bytes overhead
- Estimated time: 0.02ms
1024-byte fragments:
- 9 TLS records
- ~261 bytes overhead (9x more)
- Estimated time: 1.1ms (55x slower)
For 50KB messages:
- Standard: 4 records
- Fragmented: 49 records
- Performance degradation: ~10x
Recommendation
For ship-go specifically:
-
Document the limitation clearly
- This is a Go platform constraint
- Reference Go issue #20420 (open since 2017)
- Explain performance implications
-
If compliance is mandatory, use the proxy approach:
- Least invasive to codebase
- Maintains Go's security benefits
- Can be optional deployment configuration
- 1-2 week implementation
-
Work on specification amendment
- The requirement predates modern IoT capabilities
- Performance impact outweighs benefits
- Most implementations likely don't comply
Cost-Benefit Analysis
Costs of Implementation:
- Engineering: 1-2 weeks (proxy) to 3-4 months (OpenSSL)
- Performance: 5-10x overhead on TLS operations
- Complexity: Additional components to maintain
- Security: Increased attack surface
Benefits:
- Specification compliance checkbox
- Potential memory savings on extremely constrained devices
- No functional improvements (protocol works without this)
Conclusion: The engineering effort significantly outweighs the minimal benefits. This requirement should be addressed through specification amendment rather than complex implementation workarounds.
References
- SHIP Technical Specification v1.0.1, Section 9.2
- Go issue #20420: "proposal: crypto/tls: customizable max record size"
- OpenSSL Documentation: SSL_CTX_set_max_send_fragment()
- stunnel Documentation: Fragment size configuration