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  }