golang/go · error

crypto/sha512: invalid hash state size

Error message

crypto/sha512: invalid hash state size

What it means

Returned by sha384Hash.UnmarshalBinary after both prefix checks pass but the total length is not marshaledSize512. Guards the fixed-shape decode that follows (8 uint64 state words, 128-byte block, 8-byte counter).

Source

Thrown at src/crypto/internal/boring/sha.go:524

	b = byteorder.BEAppendUint64(b, d.h[4])
	b = byteorder.BEAppendUint64(b, d.h[5])
	b = byteorder.BEAppendUint64(b, d.h[6])
	b = byteorder.BEAppendUint64(b, d.h[7])
	b = append(b, d.x[:d.nx]...)
	b = append(b, make([]byte, len(d.x)-int(d.nx))...)
	b = byteorder.BEAppendUint64(b, d.nl>>3|d.nh<<61)
	return b, nil
}

func (h *sha384Hash) UnmarshalBinary(b []byte) error {
	if len(b) < len(magic512) {
		return errors.New("crypto/sha512: invalid hash state identifier")
	}
	if string(b[:len(magic384)]) != magic384 {
		return errors.New("crypto/sha512: invalid hash state identifier")
	}
	if len(b) != marshaledSize512 {
		return errors.New("crypto/sha512: invalid hash state size")
	}
	d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
	b = b[len(magic512):]
	b, d.h[0] = consumeUint64(b)
	b, d.h[1] = consumeUint64(b)
	b, d.h[2] = consumeUint64(b)
	b, d.h[3] = consumeUint64(b)
	b, d.h[4] = consumeUint64(b)
	b, d.h[5] = consumeUint64(b)
	b, d.h[6] = consumeUint64(b)
	b, d.h[7] = consumeUint64(b)
	b = b[copy(d.x[:], b):]
	b, n := consumeUint64(b)
	d.nl = n << 3
	d.nh = n >> 61
	d.nx = uint32(n) % 128
	return nil
}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Validate length == marshaledSize512 before unmarshalling.
  2. Regenerate the blob from the current Go build.
  3. Re-hash instead of persisting state.

Example fix

// before
h := sha512.New384()
h.(encoding.BinaryUnmarshalser).UnmarshalBinary(state)
// after
if len(state) != expectedLen512 { return errors.New("bad sha384 state size") }
h.(encoding.BinaryUnmarshalser).UnmarshalBinary(state)
Defensive patterns

Strategy: validation

Validate before calling

// marshaledSize512 for the BoringCrypto SHA-512 build
const sha512MarshaledSize = 6 + 8*8 + 128 + 8 // = 206
func validSHA384State(s []byte) bool {
    return len(s) == sha512MarshaledSize
}

Type guard

// n/a

Try / catch

if err := h384.(encoding.BinaryUnmarshalser).UnmarshalBinary(state); err != nil {
    return err
}

Prevention

When it happens

Trigger: Calling UnmarshalBinary on a sha512.New384() hash with a correctly-prefixed but wrong-length blob.

Common situations: Truncated/padded state; state from a different Go version whose marshalled layout changed; transport corruption.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/d0a004d372d19f47. Report an issue: GitHub.