{"record":{"id":"c571013601fa20c8","repo":"AlexxIT/go2rtc","slug":"w-v","errorCode":null,"errorMessage":"%w: %v","messagePattern":"%w: %v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/tutk/dtls/cipher.go","lineNumber":116,"sourceCode":"\nfunc (c *ChaCha20Poly1305Cipher) Decrypt(header recordlayer.Header, in []byte) ([]byte, error) {\n\terr := header.Unmarshal(in)\n\tswitch {\n\tcase err != nil:\n\t\treturn nil, err\n\tcase header.ContentType == protocol.ContentTypeChangeCipherSpec:\n\t\treturn in, nil\n\tcase len(in) <= header.Size()+chachaTagLength:\n\t\treturn nil, fmt.Errorf(\"ciphertext too short: %d <= %d\", len(in), header.Size()+chachaTagLength)\n\t}\n\n\tnonce := computeNonce(c.remoteWriteIV, header.Epoch, header.SequenceNumber)\n\tout := in[header.Size():]\n\tadditionalData := generateAEADAdditionalData(&header, len(out)-chachaTagLength)\n\n\tout, err = c.remoteCipher.Open(out[:0], nonce, out, additionalData)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: %v\", errDecryptPacket, err)\n\t}\n\n\treturn append(in[:header.Size()], out...), nil\n}\n\ntype TLSEcdhePskWithChacha20Poly1305Sha256 struct {\n\taead atomic.Value\n}\n\nfunc NewTLSEcdhePskWithChacha20Poly1305Sha256() *TLSEcdhePskWithChacha20Poly1305Sha256 {\n\treturn &TLSEcdhePskWithChacha20Poly1305Sha256{}\n}\n\nfunc (c *TLSEcdhePskWithChacha20Poly1305Sha256) CertificateType() clientcertificate.Type {\n\treturn clientcertificate.Type(0)\n}\n\nfunc (c *TLSEcdhePskWithChacha20Poly1305Sha256) KeyExchangeAlgorithm() dtls.CipherSuiteKeyExchangeAlgorithm {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/tutk/dtls/cipher.go#L98-L134","documentation":"When the AEAD Open (authenticated decryption) fails — typically because the Poly1305 tag does not verify — Decrypt wraps the underlying error as '<errDecryptPacket>: <detail>'. This means the record failed authentication: wrong key material, wrong nonce, or corrupted/altered ciphertext.","triggerScenarios":"Calling Decrypt when remoteCipher.Open returns an error: packet bytes corrupted in transit, replayed/reordered records producing wrong epoch/sequence nonce, or DTLS keys not synchronized (peer rekeyed mid-session).","commonSituations":"UDP packet corruption or tampering; handshake completed with mismatched keys (e.g. PSK differs between peers); sequence-number desync after dropped/reordered datagrams; replay of old packets.","solutions":["Check PSK/session key agreement — both sides must derive identical keys (verify credentials/handshake).","Ensure records are processed in order and sequence numbers/epochs match; drop replays before decrypt.","Enable DTLS retransmission/anti-replay handling on the transport and retransmit lost handshake flights.","If corruption is environmental (bad Wi-Fi/cabling), fix the link layer or add per-record retransmission."],"exampleFix":"// before\nout, err := cipher.Decrypt(h, raw)\nif err != nil { return err }\n// after\nout, err := cipher.Decrypt(h, raw)\nif err != nil {\n\tlog.Printf(\"dtls decrypt failed (seq=%d): %v\", h.SequenceNumber, err)\n\treturn nil // drop inauthentic record, don't crash session\n}","handlingStrategy":"try-catch","validationCode":"// Drop replays and out-of-order records before decrypting\nif h.SequenceNumber <= lastSeenSeq || h.Epoch != expectedEpoch {\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"out, err := cipher.Decrypt(h, raw)\nif err != nil {\n\tif errors.Is(err, errDecryptPacket) {\n\t\tlog.Printf(\"inauthentic record seq=%d: %v\", h.SequenceNumber, err)\n\t\treturn nil // drop record, keep session\n\t}\n\treturn err\n}","preventionTips":["Verify PSK/credentials match on both peers","Process records in order and enforce anti-replay windows","Retransmit lost handshake flights to avoid key desync","Fix physical link issues if corruption rates are high"],"tags":["dtls","crypto","tls","authentication"],"backgroundTag":"checksum-mismatch","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}