github.com/emmansun/gmsm@v0.29.1/sm4/sm4_xts.go (about) 1 //go:build (amd64 || arm64) && !purego 2 3 package sm4 4 5 import ( 6 "crypto/cipher" 7 8 "github.com/emmansun/gmsm/internal/alias" 9 ) 10 11 // Assert that sm4CipherAsm implements the xtsEncAble and xtsDecAble interfaces. 12 var _ xtsEncAble = (*sm4CipherAsm)(nil) 13 var _ xtsDecAble = (*sm4CipherAsm)(nil) 14 15 const xtsEncrypt = 1 16 const xtsDecrypt = 0 17 18 type xts struct { 19 b *sm4CipherAsm 20 tweak [BlockSize]byte 21 isGB bool // if true, follows GB/T 17964-2021 22 enc int 23 } 24 25 func (b *sm4CipherAsm) NewXTSEncrypter(encryptedTweak *[BlockSize]byte, isGB bool) cipher.BlockMode { 26 var c xts 27 c.b = b 28 c.enc = xtsEncrypt 29 c.isGB = isGB 30 copy(c.tweak[:], encryptedTweak[:]) 31 return &c 32 } 33 34 func (b *sm4CipherAsm) NewXTSDecrypter(encryptedTweak *[BlockSize]byte, isGB bool) cipher.BlockMode { 35 var c xts 36 c.b = b 37 c.enc = xtsDecrypt 38 c.isGB = isGB 39 copy(c.tweak[:], encryptedTweak[:]) 40 return &c 41 } 42 43 func (x *xts) BlockSize() int { return BlockSize } 44 45 //go:noescape 46 func encryptSm4Xts(xk *uint32, tweak *[BlockSize]byte, dst, src []byte) 47 48 //go:noescape 49 func encryptSm4XtsGB(xk *uint32, tweak *[BlockSize]byte, dst, src []byte) 50 51 //go:noescape 52 func decryptSm4Xts(xk *uint32, tweak *[BlockSize]byte, dst, src []byte) 53 54 //go:noescape 55 func decryptSm4XtsGB(xk *uint32, tweak *[BlockSize]byte, dst, src []byte) 56 57 func validateXtsInput(dst, src []byte) { 58 if len(dst) < len(src) { 59 panic("cipher: dst is smaller than src") 60 } 61 if len(src) < BlockSize { 62 panic("cipher: src length is smaller than the block size") 63 } 64 if alias.InexactOverlap(dst[:len(src)], src) { 65 panic("cipher: invalid buffer overlap") 66 } 67 } 68 69 func (x *xts) CryptBlocks(dst, src []byte) { 70 validateXtsInput(dst, src) 71 if x.enc == xtsEncrypt { 72 if x.isGB { 73 encryptSm4XtsGB(&x.b.enc[0], &x.tweak, dst, src) 74 } else { 75 encryptSm4Xts(&x.b.enc[0], &x.tweak, dst, src) 76 } 77 } else { 78 if x.isGB { 79 decryptSm4XtsGB(&x.b.dec[0], &x.tweak, dst, src) 80 } else { 81 decryptSm4Xts(&x.b.dec[0], &x.tweak, dst, src) 82 } 83 } 84 }