VYPR
High severity7.5NVD Advisory· Published Mar 28, 2017· Updated May 13, 2026

CVE-2016-9123

CVE-2016-9123

Description

go-jose before 1.0.5 suffers from a CBC-HMAC integer overflow on 32-bit architectures. An integer overflow could lead to authentication bypass for CBC-HMAC encrypted ciphertexts on 32-bit architectures.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/square/go-joseGo
< 1.0.51.0.5

Affected products

1

Patches

1
789a4c4bd4c1

Use uint64 for all size calculations, size checks

https://github.com/square/go-joseCedric StaubSep 3, 2016via ghsa
4 files changed · +18 13
  • cipher/cbc_hmac.go+8 8 modified
    @@ -82,7 +82,7 @@ func (ctx *cbcAEAD) Overhead() int {
     // Seal encrypts and authenticates the plaintext.
     func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
     	// Output buffer -- must take care not to mangle plaintext input.
    -	ciphertext := make([]byte, len(plaintext)+ctx.Overhead())[:len(plaintext)]
    +	ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)]
     	copy(ciphertext, plaintext)
     	ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize())
     
    @@ -91,7 +91,7 @@ func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
     	cbc.CryptBlocks(ciphertext, ciphertext)
     	authtag := ctx.computeAuthTag(data, nonce, ciphertext)
     
    -	ret, out := resize(dst, len(dst)+len(ciphertext)+len(authtag))
    +	ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag)))
     	copy(out, ciphertext)
     	copy(out[len(ciphertext):], authtag)
     
    @@ -128,20 +128,20 @@ func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
     		return nil, err
     	}
     
    -	ret, out := resize(dst, len(dst)+len(plaintext))
    +	ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext)))
     	copy(out, plaintext)
     
     	return ret, nil
     }
     
     // Compute an authentication tag
     func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
    -	buffer := make([]byte, len(aad)+len(nonce)+len(ciphertext)+8)
    +	buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8)
     	n := 0
     	n += copy(buffer, aad)
     	n += copy(buffer[n:], nonce)
     	n += copy(buffer[n:], ciphertext)
    -	binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad)*8))
    +	binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8)
     
     	// According to documentation, Write() on hash.Hash never fails.
     	hmac := hmac.New(ctx.hash, ctx.integrityKey)
    @@ -153,8 +153,8 @@ func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
     // resize ensures the the given slice has a capacity of at least n bytes.
     // If the capacity of the slice is less than n, a new slice is allocated
     // and the existing data will be copied.
    -func resize(in []byte, n int) (head, tail []byte) {
    -	if cap(in) >= n {
    +func resize(in []byte, n uint64) (head, tail []byte) {
    +	if uint64(cap(in)) >= n {
     		head = in[:n]
     	} else {
     		head = make([]byte, n)
    @@ -168,7 +168,7 @@ func resize(in []byte, n int) (head, tail []byte) {
     // Apply padding
     func padBuffer(buffer []byte, blockSize int) []byte {
     	missing := blockSize - (len(buffer) % blockSize)
    -	ret, out := resize(buffer, len(buffer)+missing)
    +	ret, out := resize(buffer, uint64(len(buffer))+uint64(missing))
     	padding := bytes.Repeat([]byte{byte(missing)}, missing)
     	copy(out, padding)
     	return ret
    
  • cipher/cbc_hmac_test.go+3 3 modified
    @@ -283,7 +283,7 @@ func TestTruncatedCiphertext(t *testing.T) {
     	ct := aead.Seal(nil, nonce, data, nil)
     
     	// Truncated ciphertext, but with correct auth tag
    -	truncated, tail := resize(ct[:len(ct)-ctx.authtagBytes-2], len(ct)-2)
    +	truncated, tail := resize(ct[:len(ct)-ctx.authtagBytes-2], uint64(len(ct))-2)
     	copy(tail, ctx.computeAuthTag(nil, nonce, truncated[:len(truncated)-ctx.authtagBytes]))
     
     	// Open should fail
    @@ -313,8 +313,8 @@ func TestInvalidPaddingOpen(t *testing.T) {
     	ctx := aead.(*cbcAEAD)
     
     	// Mutated ciphertext, but with correct auth tag
    -	size := len(buffer)
    -	ciphertext, tail := resize(buffer, size+(len(key)/2))
    +	size := uint64(len(buffer))
    +	ciphertext, tail := resize(buffer, size+(uint64(len(key))/2))
     	copy(tail, ctx.computeAuthTag(nil, nonce, ciphertext[:size]))
     
     	// Open should fail (b/c of invalid padding, even though tag matches)
    
  • cipher/concat_kdf.go+1 1 modified
    @@ -32,7 +32,7 @@ type concatKDF struct {
     
     // NewConcatKDF builds a KDF reader based on the given inputs.
     func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader {
    -	buffer := make([]byte, len(algID)+len(ptyUInfo)+len(ptyVInfo)+len(supPubInfo)+len(supPrivInfo))
    +	buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo)))
     	n := 0
     	n += copy(buffer, algID)
     	n += copy(buffer[n:], ptyUInfo)
    
  • cipher/ecdh_es.go+6 1 modified
    @@ -24,8 +24,13 @@ import (
     
     // DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA.
     // It is an error to call this function with a private/public key that are not on the same
    -// curve. Callers must ensure that the keys are valid before calling this function.
    +// curve. Callers must ensure that the keys are valid before calling this function. Output
    +// size may be at most 1<<16 bytes (64 KiB).
     func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte {
    +	if size > 1<<16 {
    +		panic("ECDH-ES output size too large, must be less than 1<<16")
    +	}
    +
     	// algId, partyUInfo, partyVInfo inputs must be prefixed with the length
     	algID := lengthPrefixed([]byte(alg))
     	ptyUInfo := lengthPrefixed(apuData)
    

Vulnerability mechanics

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

References

7

News mentions

0

No linked articles in our index yet.