VYPR
Moderate severityNVD Advisory· Published Feb 11, 2026· Updated Feb 13, 2026

Pion DTLS uses random nonce generation with AES GCM ciphers risks leaking the authentication key

CVE-2026-26014

Description

Pion DTLS is a Go implementation of Datagram Transport Layer Security. Pion DTLS versions v1.0.0 through v3.0.10 and 3.1.0 use random nonce generation with AES GCM ciphers, which makes it easier for remote attackers to obtain the authentication key and spoof data by leveraging the reuse of a nonce in a session and a "forbidden attack". Upgrade to v3.0.11, v3.1.1, or later.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Pion DTLS v1.0.0 through v3.0.10 and 3.1.0 use random nonce generation with AES-GCM ciphers, enabling nonce reuse and a 'forbidden attack' that can leak the authentication key.

Pion DTLS, a Go implementation of Datagram Transport Layer Security, incorrectly generates nonces for AES-GCM cipher suites in versions v1.0.0 through v3.0.10 and 3.1.0. While the nonces are described as random, the implementation makes it possible for a remote attacker to cause nonce reuse within a single DTLS session. This cryptographic weakness is particularly dangerous because AES-GCM's security fundamentally depends on each nonce being used only once with a given key.

An attacker does not need to be authenticated to exploit this vulnerability; they only need network access to observe or inject DTLS records within an active session. By leveraging the reuse of a nonce, the attacker can mount a "forbidden attack"—a well-known cryptographic analysis that, given two ciphertexts encrypted with the same nonce and key, can recover the authentication key (the GHASH key) and forge valid records.

Successful exploitation allows a remote attacker to spoof DTLS data, injecting or modifying messages that will be accepted by the peer as legitimate. This breaks the integrity guarantees of the DTLS is designed to provide, potentially enabling man-in-the-middle attacks or other session-level compromises [1].

The vulnerability has been patched in releases v3.0.11 and v3.1.1 [3][4]. Users are strongly advised to upgrade immediately. No workaround is available for affected versions; the fix modifies the nonce generation logic to meet AES-GCM's strict requirements.

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/pion/dtls/v3Go
>= 3.1.0, < 3.1.13.1.1
github.com/pion/dtls/v2Go
<= 2.2.12
github.com/pion/dtlsGo
<= 1.5.4
github.com/pion/dtls/v3Go
< 3.0.113.0.11

Affected products

2
  • Pion/DTLSllm-create
    Range: <=3.0.10, =3.1.0
  • pion/dtlsv5
    Range: = 3.1.0

Patches

2
90e241cfec29

Backport security fix for CVE-2026-26014

https://github.com/pion/dtlstheodorsmFeb 12, 2026via ghsa
2 files changed · +4 8
  • pkg/crypto/ciphersuite/ccm.go+2 4 modified
    @@ -5,7 +5,6 @@ package ciphersuite
     
     import (
     	"crypto/aes"
    -	"crypto/rand"
     	"encoding/binary"
     	"fmt"
     
    @@ -66,9 +65,8 @@ func (c *CCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error)
     	raw = raw[:pkt.Header.Size()]
     
     	nonce := append(append([]byte{}, c.localWriteIV[:4]...), make([]byte, 8)...)
    -	if _, err := rand.Read(nonce[4:]); err != nil {
    -		return nil, err
    -	}
    +	seq64 := (uint64(pkt.Header.Epoch) << 48) | (pkt.Header.SequenceNumber & 0x0000ffffffffffff)
    +	binary.BigEndian.PutUint64(nonce[4:], seq64)
     
     	var additionalData []byte
     	if pkt.Header.ContentType == protocol.ContentTypeConnectionID {
    
  • pkg/crypto/ciphersuite/gcm.go+2 4 modified
    @@ -6,7 +6,6 @@ package ciphersuite
     import (
     	"crypto/aes"
     	"crypto/cipher"
    -	"crypto/rand"
     	"encoding/binary"
     	"fmt"
     
    @@ -60,9 +59,8 @@ func (g *GCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error)
     
     	nonce := make([]byte, gcmNonceLength)
     	copy(nonce, g.localWriteIV[:4])
    -	if _, err := rand.Read(nonce[4:]); err != nil {
    -		return nil, err
    -	}
    +	seq64 := (uint64(pkt.Header.Epoch) << 48) | (pkt.Header.SequenceNumber & 0x0000ffffffffffff)
    +	binary.BigEndian.PutUint64(nonce[4:], seq64)
     
     	var additionalData []byte
     	if pkt.Header.ContentType == protocol.ContentTypeConnectionID {
    
61762dee8217

Use sequence number for nonce in GCM ciphers (#796)

https://github.com/pion/dtlsTheodor MidtlienFeb 10, 2026via ghsa
1 file changed · +3 6
  • pkg/crypto/ciphersuite/ciphersuite.go+3 6 modified
    @@ -6,7 +6,6 @@ package ciphersuite
     
     import (
     	"crypto/cipher"
    -	"crypto/rand"
     	"encoding/binary"
     	"errors"
     	"fmt"
    @@ -83,12 +82,10 @@ func (a *aead) encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error)
     	nonce := *noncePtr
     
     	copy(nonce, a.localWriteIV[:4])
    -	if _, err := rand.Read(nonce[4:]); err != nil {
    -		// Return nonce buffer to pool
    -		a.nonceBufferPool.Put(noncePtr)
     
    -		return nil, err
    -	}
    +	// https://www.rfc-editor.org/rfc/rfc9325#name-nonce-reuse-in-tls-12
    +	seq64 := (uint64(pkt.Header.Epoch) << 48) | (pkt.Header.SequenceNumber & 0x0000ffffffffffff)
    +	binary.BigEndian.PutUint64(nonce[4:], seq64)
     
     	var additionalData []byte
     	if pkt.Header.ContentType == protocol.ContentTypeConnectionID {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.