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

Golang

Source file src/pkg/crypto/cipher/cbc.go

     1	// Copyright 2009 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	// Cipher block chaining (CBC) mode.
     6	
     7	// CBC provides confidentiality by xoring (chaining) each plaintext block
     8	// with the previous ciphertext block before applying the block cipher.
     9	
    10	// See NIST SP 800-38A, pp 10-11
    11	
    12	package cipher
    13	
    14	type cbc struct {
    15		b         Block
    16		blockSize int
    17		iv        []byte
    18		tmp       []byte
    19	}
    20	
    21	func newCBC(b Block, iv []byte) *cbc {
    22		return &cbc{
    23			b:         b,
    24			blockSize: b.BlockSize(),
    25			iv:        dup(iv),
    26			tmp:       make([]byte, b.BlockSize()),
    27		}
    28	}
    29	
    30	type cbcEncrypter cbc
    31	
    32	// NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining
    33	// mode, using the given Block. The length of iv must be the same as the
    34	// Block's block size.
    35	func NewCBCEncrypter(b Block, iv []byte) BlockMode {
    36		return (*cbcEncrypter)(newCBC(b, iv))
    37	}
    38	
    39	func (x *cbcEncrypter) BlockSize() int { return x.blockSize }
    40	
    41	func (x *cbcEncrypter) CryptBlocks(dst, src []byte) {
    42		for len(src) > 0 {
    43			for i := 0; i < x.blockSize; i++ {
    44				x.iv[i] ^= src[i]
    45			}
    46			x.b.Encrypt(x.iv, x.iv)
    47			for i := 0; i < x.blockSize; i++ {
    48				dst[i] = x.iv[i]
    49			}
    50			src = src[x.blockSize:]
    51			dst = dst[x.blockSize:]
    52		}
    53	}
    54	
    55	type cbcDecrypter cbc
    56	
    57	// NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining
    58	// mode, using the given Block. The length of iv must be the same as the
    59	// Block's block size and must match the iv used to encrypt the data.
    60	func NewCBCDecrypter(b Block, iv []byte) BlockMode {
    61		return (*cbcDecrypter)(newCBC(b, iv))
    62	}
    63	
    64	func (x *cbcDecrypter) BlockSize() int { return x.blockSize }
    65	
    66	func (x *cbcDecrypter) CryptBlocks(dst, src []byte) {
    67		for len(src) > 0 {
    68			x.b.Decrypt(x.tmp, src[:x.blockSize])
    69			for i := 0; i < x.blockSize; i++ {
    70				x.tmp[i] ^= x.iv[i]
    71				x.iv[i] = src[i]
    72				dst[i] = x.tmp[i]
    73			}
    74	
    75			src = src[x.blockSize:]
    76			dst = dst[x.blockSize:]
    77		}
    78	}