From 7c4ff4bd30058edca7c7a9cd2a58682d88fbdfe7 Mon Sep 17 00:00:00 2001 From: Christopher Patton Date: Fri, 17 Jul 2026 15:43:22 -0700 Subject: [PATCH] expander: panic if requested output length overflows DST. As required by RFC 9380, the DST encodes the requested length as a 2 byte integer. If the length exceeds 2^16 - 1, then panic. The API already documents this behavior, but doesn't actually implement it as documented. --- expander/expander.go | 6 +++++- expander/expander_test.go | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/expander/expander.go b/expander/expander.go index 655a216cf..96968b098 100644 --- a/expander/expander.go +++ b/expander/expander.go @@ -95,8 +95,12 @@ func NewExpanderXOF(id xof.ID, kSecLevel uint, dst []byte) *expanderXOF { return &expanderXOF{id, kSecLevel, dst} } -// Expand panics if output's length is longer than 2^16 bytes. +// Expand panics if output's length exceeds 65535 bytes. func (e *expanderXOF) Expand(in []byte, n uint) []byte { + if n >= 1<<16 { + panic(errorLongOutput) + } + bLen := []byte{0, 0} binary.BigEndian.PutUint16(bLen, uint16(n)) pseudo := make([]byte, n) diff --git a/expander/expander_test.go b/expander/expander_test.go index fc02c9370..857d322b8 100644 --- a/expander/expander_test.go +++ b/expander/expander_test.go @@ -38,6 +38,20 @@ func TestExpander(t *testing.T) { } } +func TestXOFExpandLengthLimit(t *testing.T) { + exp := expander.NewExpanderXOF(xof.SHAKE128, 128, []byte("dst")) + if got := exp.Expand(nil, 1<<16-1); len(got) != 1<<16-1 { + t.Fatalf("unexpected output length: got %d, want %d", len(got), 1<<16-1) + } + + defer func() { + if recover() == nil { + t.Fatal("Expand did not panic for an output length exceeding 65535 bytes") + } + }() + exp.Expand(nil, 1<<16) +} + func (vs *vectorExpanderSuite) testExpander(t *testing.T) { var exp expander.Expander switch vs.Hash {