github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/bccsp/sw/sm4.go (about) 1 package sw 2 3 import ( 4 "bytes" 5 "crypto/cipher" 6 "crypto/rand" 7 "errors" 8 "fmt" 9 "io" 10 11 "github.com/hellobchain/third_party/hyperledger/fabric/bccsp" 12 "github.com/hellobchain/newcryptosm/sm4" 13 ) 14 15 // GetRandomBytes returns len random looking bytes 16 func GetSM4RandomBytes(len int) ([]byte, error) { 17 if len < 0 { 18 return nil, errors.New("Len must be larger than 0") 19 } 20 21 buffer := make([]byte, len) 22 23 n, err := rand.Read(buffer) 24 if err != nil { 25 return nil, err 26 } 27 if n != len { 28 return nil, fmt.Errorf("Buffer not filled. Requested [%d], got [%d]", len, n) 29 } 30 31 return buffer, nil 32 } 33 34 func sm4Pkcs7Padding(src []byte) []byte { 35 padding := sm4.BlockSize - len(src)%sm4.BlockSize 36 padtext := bytes.Repeat([]byte{byte(padding)}, padding) 37 return append(src, padtext...) 38 } 39 40 func sm4Pkcs7UnPadding(src []byte) ([]byte, error) { 41 length := len(src) 42 unpadding := int(src[length-1]) 43 44 if unpadding > sm4.BlockSize || unpadding == 0 { 45 return nil, errors.New("Invalid pkcs7 padding (unpadding > sm4.BlockSize || unpadding == 0)") 46 } 47 48 pad := src[len(src)-unpadding:] 49 for i := 0; i < unpadding; i++ { 50 if pad[i] != byte(unpadding) { 51 return nil, errors.New("Invalid pkcs7 padding (pad[i] != unpadding)") 52 } 53 } 54 55 return src[:(length - unpadding)], nil 56 } 57 58 func sm4CBCEncrypt(key, s []byte) ([]byte, error) { 59 if len(s)%sm4.BlockSize != 0 { 60 return nil, errors.New("Invalid plaintext. It must be a multiple of the block size") 61 } 62 63 block, err := sm4.NewCipher(key) 64 if err != nil { 65 return nil, err 66 } 67 68 ciphertext := make([]byte, sm4.BlockSize+len(s)) 69 iv := ciphertext[:sm4.BlockSize] 70 if _, err := io.ReadFull(rand.Reader, iv); err != nil { 71 return nil, err 72 } 73 74 mode := cipher.NewCBCEncrypter(block, iv) 75 mode.CryptBlocks(ciphertext[sm4.BlockSize:], s) 76 77 return ciphertext, nil 78 } 79 80 func sm4CBCDecrypt(key, src []byte) ([]byte, error) { 81 block, err := sm4.NewCipher(key) 82 if err != nil { 83 return nil, err 84 } 85 86 if len(src) < sm4.BlockSize { 87 return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size") 88 } 89 iv := src[:sm4.BlockSize] 90 src = src[sm4.BlockSize:] 91 92 if len(src)%sm4.BlockSize != 0 { 93 return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size") 94 } 95 96 mode := cipher.NewCBCDecrypter(block, iv) 97 98 mode.CryptBlocks(src, src) 99 100 return src, nil 101 } 102 103 // SM4CBCPKCS7Encrypt combines CBC encryption and PKCS7 padding 104 func SM4CBCPKCS7Encrypt(key, src []byte) ([]byte, error) { 105 // First pad 106 tmp := sm4Pkcs7Padding(src) 107 108 // Then encrypt 109 return sm4CBCEncrypt(key, tmp) 110 } 111 112 // SM4CBCPKCS7Decrypt combines CBC decryption and PKCS7 unpadding 113 func SM4CBCPKCS7Decrypt(key, src []byte) ([]byte, error) { 114 // First decrypt 115 pt, err := sm4CBCDecrypt(key, src) 116 if err == nil { 117 return sm4Pkcs7UnPadding(pt) 118 } 119 return nil, err 120 } 121 122 type sm4cbcpkcs7Encryptor struct{} 123 124 func (*sm4cbcpkcs7Encryptor) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) (ciphertext []byte, err error) { 125 // switch opts.(type) { 126 // case *bccsp.SM4CBCPKCS7ModeOpts, bccsp.SM4CBCPKCS7ModeOpts: 127 // // SM4 in CBC mode with PKCS7 padding 128 // return SM4CBCPKCS7Encrypt(k.(*sm4PrivateKey).privKey, plaintext) 129 // default: 130 // return nil, fmt.Errorf("Mode not recognized [%s]", opts) 131 // } 132 return SM4CBCPKCS7Encrypt(k.(*symmetryPrivateKey).privKey, plaintext) 133 } 134 135 type sm4cbcpkcs7Decryptor struct{} 136 137 func (*sm4cbcpkcs7Decryptor) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) { 138 // check for mode 139 // switch opts.(type) { 140 // case *bccsp.SM4CBCPKCS7ModeOpts, bccsp.SM4CBCPKCS7ModeOpts: 141 // // SM4 in CBC mode with PKCS7 padding 142 // return SM4CBCPKCS7Decrypt(k.(*sm4PrivateKey).privKey, ciphertext) 143 // default: 144 // return nil, fmt.Errorf("Mode not recognized [%s]", opts) 145 // } 146 return SM4CBCPKCS7Decrypt(k.(*symmetryPrivateKey).privKey, ciphertext) 147 }