85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package pbkd
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"xdx.jelly/xgcl/sm/sm4"
|
|
"xdx.jelly/xgcl/utils/padding"
|
|
)
|
|
|
|
const (
|
|
ENCRYPT = iota
|
|
DECRYPT
|
|
)
|
|
|
|
type Pbeser interface {
|
|
// EncryptBlocks
|
|
EncryptBlocks(dst, src []byte) ([]byte, error)
|
|
DecryptBlocks(dst, src []byte) ([]byte, error)
|
|
|
|
EncryptWithPadding(src []byte) ([]byte, error)
|
|
DecryptWithPadding(src []byte) ([]byte, error)
|
|
|
|
ResetIv(iv []byte) error
|
|
}
|
|
|
|
type PbesWithSm4Cbc struct {
|
|
key []byte
|
|
iv []byte
|
|
}
|
|
|
|
var errOperation = errors.New("error operation")
|
|
var errInvalidIV = errors.New("invalid iv length")
|
|
|
|
func NewPbesWithSm4Cbc(password, salt []byte, count int, iv []byte) (Pbeser, error) {
|
|
key, err := PbkdfWithHmacSm3(password, salt, count, int64(sm4.BlockSize))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(iv) != sm4.BlockSize {
|
|
return nil, errInvalidIV
|
|
}
|
|
|
|
myIv := make([]byte, sm4.BlockSize)
|
|
copy(myIv, iv)
|
|
|
|
return &PbesWithSm4Cbc{
|
|
key: key,
|
|
iv: myIv,
|
|
}, nil
|
|
}
|
|
|
|
func (pbes *PbesWithSm4Cbc) EncryptBlocks(dst, src []byte) ([]byte, error) {
|
|
return sm4.EncryptCBC(dst, pbes.iv, pbes.key, src)
|
|
}
|
|
|
|
func (pbes *PbesWithSm4Cbc) DecryptBlocks(dst, src []byte) ([]byte, error) {
|
|
return sm4.EncryptCBC(dst, pbes.iv, pbes.key, src)
|
|
}
|
|
|
|
func (pbes *PbesWithSm4Cbc) EncryptWithPadding(src []byte) ([]byte, error) {
|
|
pad := padding.P7.Pad(src, sm4.BlockSize)
|
|
return sm4.EncryptCBC(nil, pbes.iv, pbes.key, pad)
|
|
}
|
|
|
|
func (pbes *PbesWithSm4Cbc) DecryptWithPadding(src []byte) ([]byte, error) {
|
|
dst, err := sm4.DecryptCBC(nil, pbes.iv, pbes.key, src)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
dst, err = padding.P7.Unpad(dst, sm4.BlockSize)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return dst, nil
|
|
}
|
|
|
|
func (pbes *PbesWithSm4Cbc) ResetIv(iv []byte) error {
|
|
if len(iv) != sm4.BlockSize {
|
|
return errInvalidIV
|
|
}
|
|
copy(pbes.iv, iv)
|
|
return nil
|
|
}
|