github.com/mad-day/Yawning-crypto@v0.0.0-20190711051033-5a5f8cca32ec/bsaes/internal/modes/cbc.go (about) 1 // Copyright (c) 2017 Yawning Angel <yawning at schwanenlied dot me> 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining 4 // a copy of this software and associated documentation files (the 5 // "Software"), to deal in the Software without restriction, including 6 // without limitation the rights to use, copy, modify, merge, publish, 7 // distribute, sublicense, and/or sell copies of the Software, and to 8 // permit persons to whom the Software is furnished to do so, subject to 9 // the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be 12 // included in all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 18 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 // SOFTWARE. 22 23 package modes 24 25 import "crypto/cipher" 26 27 func (m *BlockModesImpl) NewCBCDecrypter(iv []byte) cipher.BlockMode { 28 ecb := m.b.(bulkECBAble) 29 if len(iv) != ecb.BlockSize() { 30 panic("bsaes/NewCBCDecrypter: iv size does not match block size") 31 } 32 33 return newCBCDecImpl(ecb, iv) 34 } 35 36 type cbcDecImpl struct { 37 ecb bulkECBAble 38 iv []byte 39 buf []byte 40 tmp [blockSize]byte 41 42 stride int 43 } 44 45 func (c *cbcDecImpl) BlockSize() int { 46 return blockSize 47 } 48 49 func (c *cbcDecImpl) CryptBlocks(dst, src []byte) { 50 sLen := len(src) 51 if sLen == 0 { 52 return 53 } 54 n := sLen / blockSize 55 56 for n >= c.stride { // Stride blocks at a time. 57 copy(c.iv[blockSize:], src) 58 copy(c.tmp[:], src[(c.stride-1)*blockSize:]) 59 60 c.ecb.BulkDecrypt(c.buf, src) 61 for i, v := range c.iv { 62 dst[i] = c.buf[i] ^ v 63 } 64 65 copy(c.iv, c.tmp[:]) 66 dst, src = dst[c.stride*blockSize:], src[c.stride*blockSize:] 67 n -= c.stride 68 } 69 for n > 0 { // Process the remainder one block at a time. 70 copy(c.tmp[:], src[:blockSize]) 71 72 c.ecb.Decrypt(c.buf, src[:blockSize]) 73 for i, v := range c.iv[:blockSize] { 74 dst[i] = c.buf[i] ^ v 75 } 76 77 copy(c.iv, c.tmp[:]) 78 dst, src = dst[blockSize:], src[blockSize:] 79 n-- 80 } 81 } 82 83 func newCBCDecImpl(ecb bulkECBAble, iv []byte) cipher.BlockMode { 84 c := new(cbcDecImpl) 85 c.ecb = ecb 86 c.stride = ecb.Stride() 87 c.iv = make([]byte, c.stride*blockSize) 88 copy(c.iv, iv) 89 c.buf = make([]byte, c.stride*blockSize) 90 91 return c 92 }