github.com/emmansun/gmsm@v0.29.1/sm4/cbc_cipher_asm.go (about) 1 //go:build (amd64 || arm64 || ppc64 || ppc64le) && !purego 2 3 package sm4 4 5 import ( 6 "crypto/cipher" 7 8 "github.com/emmansun/gmsm/internal/alias" 9 "github.com/emmansun/gmsm/internal/subtle" 10 ) 11 12 // Assert that sm4CipherAsm implements the cbcEncAble and cbcDecAble interfaces. 13 var _ cbcEncAble = (*sm4CipherAsm)(nil) 14 var _ cbcDecAble = (*sm4CipherAsm)(nil) 15 16 const cbcEncrypt = 1 17 const cbcDecrypt = 0 18 19 type cbc struct { 20 b *sm4CipherAsm 21 iv []byte 22 enc int 23 } 24 25 func (b *sm4CipherAsm) NewCBCEncrypter(iv []byte) cipher.BlockMode { 26 var c cbc 27 c.b = b 28 c.enc = cbcEncrypt 29 c.iv = make([]byte, BlockSize) 30 copy(c.iv, iv) 31 return &c 32 } 33 34 func (b *sm4CipherAsm) NewCBCDecrypter(iv []byte) cipher.BlockMode { 35 var c cbc 36 c.b = b 37 c.enc = cbcDecrypt 38 c.iv = make([]byte, BlockSize) 39 copy(c.iv, iv) 40 return &c 41 } 42 43 func (x *cbc) BlockSize() int { return BlockSize } 44 45 //go:noescape 46 func decryptBlocksChain(xk *uint32, dst, src []byte, iv *byte) 47 48 func (x *cbc) CryptBlocks(dst, src []byte) { 49 if len(src)%BlockSize != 0 { 50 panic("cipher: input not full blocks") 51 } 52 if len(dst) < len(src) { 53 panic("cipher: output smaller than input") 54 } 55 if alias.InexactOverlap(dst[:len(src)], src) { 56 panic("cipher: invalid buffer overlap") 57 } 58 if len(src) == 0 { 59 return 60 } 61 if x.enc == cbcEncrypt { 62 iv := x.iv 63 64 for len(src) >= BlockSize { 65 // Write the xor to dst, then encrypt in place. 66 subtle.XORBytes(dst[:BlockSize], src[:BlockSize], iv) 67 x.b.encrypt(dst[:BlockSize], dst[:BlockSize]) 68 69 // Move to the next block with this block as the next iv. 70 iv = dst[:BlockSize] 71 src = src[BlockSize:] 72 dst = dst[BlockSize:] 73 } 74 75 // Save the iv for the next CryptBlocks call. 76 copy(x.iv, iv) 77 return 78 } 79 80 decryptBlocksChain(&x.b.dec[0], dst, src, &x.iv[0]) 81 } 82 83 func (x *cbc) SetIV(iv []byte) { 84 if len(iv) != BlockSize { 85 panic("cipher: incorrect length IV") 86 } 87 copy(x.iv[:], iv) 88 }