Source file src/crypto/cipher/cfb.go

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // CFB (Cipher Feedback) Mode.
     6  
     7  package cipher
     8  
     9  import (
    10  	"crypto/internal/fips140/alias"
    11  	"crypto/internal/fips140only"
    12  	"crypto/subtle"
    13  )
    14  
    15  type cfb struct {
    16  	b       Block
    17  	next    []byte
    18  	out     []byte
    19  	outUsed int
    20  
    21  	decrypt bool
    22  }
    23  
    24  func (x *cfb) XORKeyStream(dst, src []byte) {
    25  	if len(dst) < len(src) {
    26  		panic("crypto/cipher: output smaller than input")
    27  	}
    28  	if alias.InexactOverlap(dst[:len(src)], src) {
    29  		panic("crypto/cipher: invalid buffer overlap")
    30  	}
    31  	for len(src) > 0 {
    32  		if x.outUsed == len(x.out) {
    33  			x.b.Encrypt(x.out, x.next)
    34  			x.outUsed = 0
    35  		}
    36  
    37  		if x.decrypt {
    38  			// We can precompute a larger segment of the
    39  			// keystream on decryption. This will allow
    40  			// larger batches for xor, and we should be
    41  			// able to match CTR/OFB performance.
    42  			copy(x.next[x.outUsed:], src)
    43  		}
    44  		n := subtle.XORBytes(dst, src, x.out[x.outUsed:])
    45  		if !x.decrypt {
    46  			copy(x.next[x.outUsed:], dst)
    47  		}
    48  		dst = dst[n:]
    49  		src = src[n:]
    50  		x.outUsed += n
    51  	}
    52  }
    53  
    54  // NewCFBEncrypter returns a [Stream] which encrypts with cipher feedback mode,
    55  // using the given [Block]. The iv must be the same length as the [Block]'s block
    56  // size.
    57  //
    58  // Deprecated: CFB mode is not authenticated, which generally enables active
    59  // attacks to manipulate and recover the plaintext. It is recommended that
    60  // applications use [AEAD] modes instead. The standard library implementation of
    61  // CFB is also unoptimized and not validated as part of the FIPS 140-3 module.
    62  // If an unauthenticated [Stream] mode is required, use [NewCTR] instead.
    63  func NewCFBEncrypter(block Block, iv []byte) Stream {
    64  	if fips140only.Enabled {
    65  		panic("crypto/cipher: use of CFB is not allowed in FIPS 140-only mode")
    66  	}
    67  	return newCFB(block, iv, false)
    68  }
    69  
    70  // NewCFBDecrypter returns a [Stream] which decrypts with cipher feedback mode,
    71  // using the given [Block]. The iv must be the same length as the [Block]'s block
    72  // size.
    73  //
    74  // Deprecated: CFB mode is not authenticated, which generally enables active
    75  // attacks to manipulate and recover the plaintext. It is recommended that
    76  // applications use [AEAD] modes instead. The standard library implementation of
    77  // CFB is also unoptimized and not validated as part of the FIPS 140-3 module.
    78  // If an unauthenticated [Stream] mode is required, use [NewCTR] instead.
    79  func NewCFBDecrypter(block Block, iv []byte) Stream {
    80  	if fips140only.Enabled {
    81  		panic("crypto/cipher: use of CFB is not allowed in FIPS 140-only mode")
    82  	}
    83  	return newCFB(block, iv, true)
    84  }
    85  
    86  func newCFB(block Block, iv []byte, decrypt bool) Stream {
    87  	blockSize := block.BlockSize()
    88  	if len(iv) != blockSize {
    89  		// stack trace will indicate whether it was de or encryption
    90  		panic("cipher.newCFB: IV length must equal block size")
    91  	}
    92  	x := &cfb{
    93  		b:       block,
    94  		out:     make([]byte, blockSize),
    95  		next:    make([]byte, blockSize),
    96  		outUsed: blockSize,
    97  		decrypt: decrypt,
    98  	}
    99  	copy(x.next, iv)
   100  
   101  	return x
   102  }
   103  

View as plain text