src/pkg/crypto/cipher/cfb.go - The Go Programming Language

Golang

Source file src/pkg/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	type cfb struct {
    10		b       Block
    11		out     []byte
    12		outUsed int
    13		decrypt bool
    14	}
    15	
    16	// NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode,
    17	// using the given Block. The iv must be the same length as the Block's block
    18	// size.
    19	func NewCFBEncrypter(block Block, iv []byte) Stream {
    20		return newCFB(block, iv, false)
    21	}
    22	
    23	// NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode,
    24	// using the given Block. The iv must be the same length as the Block's block
    25	// size.
    26	func NewCFBDecrypter(block Block, iv []byte) Stream {
    27		return newCFB(block, iv, true)
    28	}
    29	
    30	func newCFB(block Block, iv []byte, decrypt bool) Stream {
    31		blockSize := block.BlockSize()
    32		if len(iv) != blockSize {
    33			return nil
    34		}
    35	
    36		x := &cfb{
    37			b:       block,
    38			out:     make([]byte, blockSize),
    39			outUsed: 0,
    40			decrypt: decrypt,
    41		}
    42		block.Encrypt(x.out, iv)
    43	
    44		return x
    45	}
    46	
    47	func (x *cfb) XORKeyStream(dst, src []byte) {
    48		for i := 0; i < len(src); i++ {
    49			if x.outUsed == len(x.out) {
    50				x.b.Encrypt(x.out, x.out)
    51				x.outUsed = 0
    52			}
    53	
    54			if x.decrypt {
    55				t := src[i]
    56				dst[i] = src[i] ^ x.out[x.outUsed]
    57				x.out[x.outUsed] = t
    58			} else {
    59				x.out[x.outUsed] ^= src[i]
    60				dst[i] = x.out[x.outUsed]
    61			}
    62			x.outUsed++
    63		}
    64	}