53 lines
1.0 KiB
Go
53 lines
1.0 KiB
Go
package sbproxy
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/sha256"
|
|
)
|
|
|
|
type cfb8 struct {
|
|
block cipher.Block
|
|
iv []byte
|
|
tmp []byte
|
|
decrypt bool
|
|
}
|
|
|
|
func NewCFB8(block cipher.Block, iv []byte, decrypt bool) cipher.Stream {
|
|
bs := block.BlockSize()
|
|
if len(iv) != bs {
|
|
panic("cfb8: IV length must equal block size")
|
|
}
|
|
return &cfb8{
|
|
block: block,
|
|
iv: append([]byte(nil), iv...),
|
|
tmp: make([]byte, bs),
|
|
decrypt: decrypt,
|
|
}
|
|
}
|
|
|
|
func (x *cfb8) XORKeyStream(dst, src []byte) {
|
|
for i := range src {
|
|
x.block.Encrypt(x.tmp, x.iv)
|
|
val := src[i]
|
|
dst[i] = val ^ x.tmp[0]
|
|
if x.decrypt {
|
|
copy(x.iv, x.iv[1:])
|
|
x.iv[len(x.iv)-1] = val
|
|
} else {
|
|
copy(x.iv, x.iv[1:])
|
|
x.iv[len(x.iv)-1] = dst[i]
|
|
}
|
|
}
|
|
}
|
|
|
|
func NewCipherStream(password string, decrypt bool) (cipher.Stream, error) {
|
|
key := sha256.Sum256([]byte(password))
|
|
block, err := aes.NewCipher(key[:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Use first 16 bytes of Hash as IV
|
|
return NewCFB8(block, key[:16], decrypt), nil
|
|
}
|