github.com/wfusion/gofusion@v1.1.14/common/utils/cipher/types.go (about)

     1  package cipher
     2  
     3  import (
     4  	"crypto/aes"
     5  	"crypto/cipher"
     6  	"crypto/des"
     7  	"crypto/rc4"
     8  	"errors"
     9  
    10  	"github.com/tjfoc/gmsm/sm4"
    11  	"golang.org/x/crypto/chacha20poly1305"
    12  )
    13  
    14  type blockMode interface {
    15  	CipherMode() Mode
    16  	PlainBlockSize() int
    17  	CipherBlockSize() int
    18  	CryptBlocks(dst, src, buf []byte) (n int, err error)
    19  }
    20  
    21  const (
    22  	RndSeed int64 = -3250455768463625913
    23  )
    24  
    25  var (
    26  	// ErrNotSupportStream for stream encryption
    27  	ErrNotSupportStream = errors.New("not support stream encryption mode")
    28  )
    29  
    30  var (
    31  	cipherBlockMapping = map[Algorithm]func(key []byte) (cipher.Block, error){
    32  		AlgorithmDES:  func(key []byte) (cipher.Block, error) { return des.NewCipher(key) },
    33  		Algorithm3DES: func(key []byte) (cipher.Block, error) { return des.NewTripleDESCipher(key) },
    34  		AlgorithmAES:  func(key []byte) (cipher.Block, error) { return aes.NewCipher(key) },
    35  		AlgorithmSM4:  func(key []byte) (cipher.Block, error) { return sm4.NewCipher(key) },
    36  	}
    37  
    38  	encryptModeMapping = map[Mode]func(b cipher.Block, iv []byte) (e blockMode, err error){
    39  		ModeECB: func(b cipher.Block, iv []byte) (e blockMode, err error) {
    40  			return wrapErr(newBlockModeWrapper(
    41  				wrapBlock(b, ModeECB, true)),
    42  			)
    43  		},
    44  		ModeCBC: func(b cipher.Block, iv []byte) (e blockMode, err error) {
    45  			return wrapErr(newBlockModeWrapper(
    46  				wrapBlockMode(cipher.NewCBCEncrypter(b, iv), ModeCBC)),
    47  			)
    48  		},
    49  		ModeCFB: func(b cipher.Block, iv []byte) (e blockMode, err error) {
    50  			return wrapErr(newBlockModeWrapper(
    51  				wrapStream(cipher.NewCFBEncrypter(b, iv), ModeCFB)),
    52  			)
    53  		},
    54  		ModeCTR: func(b cipher.Block, iv []byte) (e blockMode, err error) {
    55  			return wrapErr(newBlockModeWrapper(
    56  				wrapStream(cipher.NewCTR(b, iv), ModeCTR)),
    57  			)
    58  		},
    59  		ModeOFB: func(b cipher.Block, iv []byte) (e blockMode, err error) {
    60  			return wrapErr(newBlockModeWrapper(
    61  				wrapStream(cipher.NewOFB(b, iv), ModeOFB)),
    62  			)
    63  		},
    64  		ModeGCM: func(b cipher.Block, iv []byte) (e blockMode, err error) {
    65  			aead, err := cipher.NewGCM(b)
    66  			if err != nil {
    67  				return
    68  			}
    69  			e = newAEADEncryptWrapper(aead, b.BlockSize(), ModeGCM)
    70  			return
    71  		},
    72  	}
    73  	decryptModeMapping = map[Mode]func(b cipher.Block, iv []byte) (bm blockMode, err error){
    74  		ModeECB: func(b cipher.Block, iv []byte) (e blockMode, err error) {
    75  			return wrapErr(newBlockModeWrapper(
    76  				wrapBlock(b, ModeECB, false)),
    77  			)
    78  		},
    79  		ModeCBC: func(b cipher.Block, iv []byte) (bm blockMode, err error) {
    80  			return wrapErr(newBlockModeWrapper(
    81  				wrapBlockMode(cipher.NewCBCDecrypter(b, iv), ModeCBC)),
    82  			)
    83  		},
    84  		ModeCFB: func(b cipher.Block, iv []byte) (bm blockMode, err error) {
    85  			return wrapErr(newBlockModeWrapper(
    86  				wrapStream(cipher.NewCFBDecrypter(b, iv), ModeCFB)),
    87  			)
    88  		},
    89  		ModeCTR: func(b cipher.Block, iv []byte) (bm blockMode, err error) {
    90  			return wrapErr(newBlockModeWrapper(
    91  				wrapStream(cipher.NewCTR(b, iv), ModeCTR)),
    92  			)
    93  		},
    94  		ModeOFB: func(b cipher.Block, iv []byte) (bm blockMode, err error) {
    95  			return wrapErr(newBlockModeWrapper(
    96  				wrapStream(cipher.NewOFB(b, iv), ModeOFB)),
    97  			)
    98  		},
    99  		ModeGCM: func(b cipher.Block, iv []byte) (bm blockMode, err error) {
   100  			cipherAEAD, err := cipher.NewGCM(b)
   101  			if err != nil {
   102  				return
   103  			}
   104  			bm = newAEADDecryptWrapper(cipherAEAD, b.BlockSize(), ModeGCM)
   105  			return
   106  		},
   107  	}
   108  
   109  	streamEncryptMapping = map[Algorithm]func(key []byte) (bm blockMode, err error){
   110  		AlgorithmRC4: func(key []byte) (bm blockMode, err error) {
   111  			cipher, err := rc4.NewCipher(key)
   112  			if err != nil {
   113  				return
   114  			}
   115  			bm = &rc4Wrapper{rc: cipher}
   116  			return
   117  		},
   118  		AlgorithmChaCha20poly1305: func(key []byte) (bm blockMode, err error) {
   119  			cipherAEAD, err := chacha20poly1305.New(key)
   120  			if err != nil {
   121  				return
   122  			}
   123  			bm = newAEADEncryptWrapper(cipherAEAD, defaultBlockSize, modeStream)
   124  			return
   125  		},
   126  		AlgorithmXChaCha20poly1305: func(key []byte) (bm blockMode, err error) {
   127  			cipherAEAD, err := chacha20poly1305.NewX(key)
   128  			if err != nil {
   129  				return
   130  			}
   131  			bm = newAEADEncryptWrapper(cipherAEAD, defaultBlockSize, modeStream)
   132  			return
   133  		},
   134  	}
   135  	streamDecryptMapping = map[Algorithm]func(key []byte) (bm blockMode, err error){
   136  		AlgorithmRC4: func(key []byte) (bm blockMode, err error) {
   137  			cipher, err := rc4.NewCipher(key)
   138  			if err != nil {
   139  				return
   140  			}
   141  			bm = &rc4Wrapper{rc: cipher}
   142  			return
   143  		},
   144  		AlgorithmChaCha20poly1305: func(key []byte) (bm blockMode, err error) {
   145  			cipherAEAD, err := chacha20poly1305.New(key)
   146  			if err != nil {
   147  				return
   148  			}
   149  			bm = newAEADDecryptWrapper(cipherAEAD, defaultBlockSize, modeStream)
   150  			return
   151  		},
   152  		AlgorithmXChaCha20poly1305: func(key []byte) (bm blockMode, err error) {
   153  			cipherAEAD, err := chacha20poly1305.NewX(key)
   154  			if err != nil {
   155  				return
   156  			}
   157  			bm = newAEADDecryptWrapper(cipherAEAD, defaultBlockSize, modeStream)
   158  			return
   159  		},
   160  	}
   161  )
   162  
   163  func wrapErr[T any](a T) (b T, err error) { b = a; return }