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:

  1. RFC 6066 support (SHOULD - optional)
  2. 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:

  1. Document the limitation clearly

    • This is a Go platform constraint
    • Reference Go issue #20420 (open since 2017)
    • Explain performance implications
  2. 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
  3. 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