github.com/wfusion/gofusion@v1.1.14/common/utils/cipher/block_mode_wrapper.go (about) 1 package cipher 2 3 import ( 4 "crypto/cipher" 5 6 "github.com/wfusion/gofusion/common/utils" 7 ) 8 9 type blockModeWrapper struct { 10 block cipher.Block 11 blockMode cipher.BlockMode 12 stream cipher.Stream 13 blockSize int 14 15 mode Mode 16 isEncoder bool 17 } 18 19 type blockModeOption struct { 20 block cipher.Block 21 blockMode cipher.BlockMode 22 stream cipher.Stream 23 mode Mode 24 isEncoder bool 25 } 26 27 func wrapBlock(block cipher.Block, mode Mode, isEncoder bool) utils.OptionFunc[blockModeOption] { 28 return func(o *blockModeOption) { 29 o.mode = mode 30 o.block = block 31 o.isEncoder = isEncoder 32 } 33 } 34 35 func wrapBlockMode(bm cipher.BlockMode, mode Mode) utils.OptionFunc[blockModeOption] { 36 return func(o *blockModeOption) { 37 o.mode = mode 38 o.blockMode = bm 39 } 40 } 41 42 func wrapStream(stream cipher.Stream, mode Mode) utils.OptionFunc[blockModeOption] { 43 return func(o *blockModeOption) { 44 o.mode = mode 45 o.stream = stream 46 } 47 } 48 49 func newBlockModeWrapper(opts ...utils.OptionExtender) (w *blockModeWrapper) { 50 opt := utils.ApplyOptions[blockModeOption](opts...) 51 w = &blockModeWrapper{ 52 block: opt.block, 53 blockMode: opt.blockMode, 54 stream: opt.stream, 55 blockSize: 0, 56 mode: opt.mode, 57 isEncoder: opt.isEncoder, 58 } 59 60 switch { 61 case opt.block != nil: 62 w.blockSize = w.block.BlockSize() 63 case opt.blockMode != nil: 64 w.blockSize = w.blockMode.BlockSize() 65 case opt.stream != nil: 66 w.blockSize = defaultBlockSize * blockSizeTimes 67 } 68 69 return 70 } 71 72 func (b *blockModeWrapper) CipherMode() Mode { return b.mode } 73 func (b *blockModeWrapper) PlainBlockSize() int { return b.blockSize } 74 func (b *blockModeWrapper) CipherBlockSize() int { return b.blockSize } 75 func (b *blockModeWrapper) CryptBlocks(dst, src, buf []byte) (n int, err error) { 76 if len(src) == 0 { 77 return 78 } 79 n = len(src) 80 switch { 81 case b.blockMode != nil: 82 b.blockMode.CryptBlocks(dst, src) 83 case b.block != nil: 84 if b.isEncoder { 85 b.block.Encrypt(dst, src) 86 } else { 87 b.block.Decrypt(dst, src) 88 } 89 case b.stream != nil: 90 b.stream.XORKeyStream(dst, src) 91 default: 92 copy(dst, src) 93 } 94 return 95 }