github.com/emmansun/gmsm@v0.29.1/cipher/ecb.go (about) 1 // Electronic Code Book (ECB) mode. 2 3 // Please do NOT use this mode alone. 4 package cipher 5 6 import ( 7 goCipher "crypto/cipher" 8 9 "github.com/emmansun/gmsm/internal/alias" 10 ) 11 12 type ecb struct { 13 b goCipher.Block 14 blockSize int 15 } 16 17 func newECB(b goCipher.Block) *ecb { 18 return &ecb{ 19 b: b, 20 blockSize: b.BlockSize(), 21 } 22 } 23 24 func validate(size int, dst, src []byte) { 25 if len(src)%size != 0 { 26 panic("cipher: input not full blocks") 27 } 28 if len(dst) < len(src) { 29 panic("cipher: output smaller than input") 30 } 31 if alias.InexactOverlap(dst[:len(src)], src) { 32 panic("cipher: invalid buffer overlap") 33 } 34 } 35 36 type ecbEncrypter ecb 37 38 // ecbEncAble is an interface implemented by ciphers that have a specific 39 // optimized implementation of ECB encryption, like sm4. 40 // NewECBEncrypter will check for this interface and return the specific 41 // BlockMode if found. 42 type ecbEncAble interface { 43 NewECBEncrypter() goCipher.BlockMode 44 } 45 46 // NewECBEncrypter returns a BlockMode which encrypts in electronic code book 47 // mode, using the given Block. 48 func NewECBEncrypter(b goCipher.Block) goCipher.BlockMode { 49 if ecb, ok := b.(ecbEncAble); ok { 50 return ecb.NewECBEncrypter() 51 } 52 return (*ecbEncrypter)(newECB(b)) 53 } 54 55 func (x *ecbEncrypter) BlockSize() int { return x.blockSize } 56 57 func (x *ecbEncrypter) CryptBlocks(dst, src []byte) { 58 validate(x.blockSize, dst, src) 59 60 for len(src) > 0 { 61 x.b.Encrypt(dst[:x.blockSize], src[:x.blockSize]) 62 src = src[x.blockSize:] 63 dst = dst[x.blockSize:] 64 } 65 } 66 67 type ecbDecrypter ecb 68 69 // ecbDecAble is an interface implemented by ciphers that have a specific 70 // optimized implementation of ECB decryption, like sm4. 71 // NewECBDecrypter will check for this interface and return the specific 72 // BlockMode if found. 73 type ecbDecAble interface { 74 NewECBDecrypter() goCipher.BlockMode 75 } 76 77 // NewECBDecrypter returns a BlockMode which decrypts in electronic code book 78 // mode, using the given Block. 79 func NewECBDecrypter(b goCipher.Block) goCipher.BlockMode { 80 if ecb, ok := b.(ecbDecAble); ok { 81 return ecb.NewECBDecrypter() 82 } 83 return (*ecbDecrypter)(newECB(b)) 84 } 85 86 func (x *ecbDecrypter) BlockSize() int { return x.blockSize } 87 88 func (x *ecbDecrypter) CryptBlocks(dst, src []byte) { 89 validate(x.blockSize, dst, src) 90 91 if len(src) == 0 { 92 return 93 } 94 95 for len(src) > 0 { 96 x.b.Decrypt(dst[:x.blockSize], src[:x.blockSize]) 97 src = src[x.blockSize:] 98 dst = dst[x.blockSize:] 99 } 100 }