{"record":{"id":"941120841a724625","repo":"golang/go","slug":"ciphertext-too-short","errorCode":null,"errorMessage":"ciphertext too short","messagePattern":"ciphertext too short","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/hpke/hpke.go","lineNumber":227,"sourceCode":"func (r *Recipient) Open(aad, ciphertext []byte) ([]byte, error) {\n\tif r.aead == nil {\n\t\treturn nil, errors.New(\"export-only instantiation\")\n\t}\n\tplaintext, err := r.aead.Open(nil, r.nextNonce(), ciphertext, aad)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tr.seqNum++\n\treturn plaintext, nil\n}\n\n// Open instantiates a single-use HPKE receiving HPKE context like [NewRecipient],\n// and then decrypts the provided ciphertext like [Recipient.Open] (with no aad).\n// ciphertext must be the concatenation of the encapsulated key and the actual ciphertext.\nfunc Open(k PrivateKey, kdf KDF, aead AEAD, info, ciphertext []byte) ([]byte, error) {\n\tencSize := k.KEM().encSize()\n\tif len(ciphertext) < encSize {\n\t\treturn nil, errors.New(\"ciphertext too short\")\n\t}\n\tenc, ciphertext := ciphertext[:encSize], ciphertext[encSize:]\n\tr, err := NewRecipient(enc, k, kdf, aead, info)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn r.Open(nil, ciphertext)\n}\n\n// Export produces a secret value derived from the shared key between sender and\n// recipient. length must be at most 65,535.\nfunc (r *Recipient) Export(exporterContext string, length int) ([]byte, error) {\n\tif length < 0 || length > 0xFFFF {\n\t\treturn nil, errors.New(\"invalid length\")\n\t}\n\treturn r.export(exporterContext, uint16(length))\n}\n","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/hpke/hpke.go#L209-L245","documentation":"The package-level convenience Open() expects ciphertext to be the concatenation of the KEM encapsulated key and the AEAD ciphertext. It reads the first encSize bytes (k.KEM().encSize()) as the encapsulated key; if the input is shorter than encSize, there is no encapsulated key to decapsulate and the call fails fast.","triggerScenarios":"Calling hpke.Open(k, kdf, aead, info, ciphertext) where len(ciphertext) < k.KEM().encSize(). Happens when the caller passes only the AEAD ciphertext (omitting the enc prefix), passes an empty slice, or uses a different KEM whose encSize is larger than the data.","commonSituations":"Sender used the convenience Seal() (which returns enc||ct) but receiver strips the enc prefix before calling Open(); or the framing on the wire truncated the message; or sender/recipient were provisioned with different KEMs.","solutions":["Pass the full enc||ciphertext blob exactly as returned by hpke.Seal.","Ensure sender and recipient use the same KEM so encSize matches.","Check len(ciphertext) >= k.KEM().encSize() before calling Open and surface a clearer framing error if not."],"exampleFix":"// before\nblob := []byte{} // accidentally stripped\npt, err := hpke.Open(k, kdf, aead, info, blob) // \"ciphertext too short\"\n\n// after\n// blob is enc||ct straight from hpke.Seal\npt, err := hpke.Open(k, kdf, aead, info, blob)","handlingStrategy":"validation","validationCode":"func openChecked(k hpke.PrivateKey, kdf hpke.KDF, aead hpke.AEAD, info, blob []byte) ([]byte, error) {\n    if min := k.KEM().encSize(); len(blob) < min {\n        return nil, fmt.Errorf(\"blob too short: got %d, need >= %d\", len(blob), min)\n    }\n    return hpke.Open(k, kdf, aead, info, blob)\n}","typeGuard":null,"tryCatchPattern":"pt, err := hpke.Open(k, kdf, aead, info, blob)\nif err != nil {\n    if err.Error() == \"ciphertext too short\" {\n        return nil, fmt.Errorf(\"framing error: need enc(%d)+ct, got %d\", k.KEM().encSize(), len(blob))\n    }\n    return nil, err\n}","preventionTips":["Always pass the full enc||ct blob from Seal straight through to Open without stripping.","Length-prefix the blob on the wire and verify the total before calling Open.","Keep sender and recipient KEM selections in lockstep."],"tags":["hpke","cryptography","validation","framing","go"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}