49 lines
834 B
Go
49 lines
834 B
Go
|
package server
|
||
|
|
||
|
import "crypto/cipher"
|
||
|
|
||
|
type cfb8 struct {
|
||
|
c cipher.Block
|
||
|
blockSize int
|
||
|
iv, ivReal, tmp []byte
|
||
|
de bool
|
||
|
}
|
||
|
|
||
|
func newCFB8(c cipher.Block, iv []byte, decrypt bool) cipher.Stream {
|
||
|
if len(iv) != 16 {
|
||
|
panic("bad iv length!")
|
||
|
}
|
||
|
cp := make([]byte, 256)
|
||
|
copy(cp, iv)
|
||
|
return &cfb8{
|
||
|
c: c,
|
||
|
blockSize: c.BlockSize(),
|
||
|
iv: cp[:16],
|
||
|
ivReal: cp,
|
||
|
tmp: make([]byte, 16),
|
||
|
de: decrypt,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (cf *cfb8) XORKeyStream(dst, src []byte) {
|
||
|
for i := 0; i < len(src); i++ {
|
||
|
val := src[i]
|
||
|
cf.c.Encrypt(cf.tmp, cf.iv)
|
||
|
val = val ^ cf.tmp[0]
|
||
|
|
||
|
if cap(cf.iv) >= 17 {
|
||
|
cf.iv = cf.iv[1:17]
|
||
|
} else {
|
||
|
copy(cf.ivReal, cf.iv[1:])
|
||
|
cf.iv = cf.ivReal[:16]
|
||
|
}
|
||
|
|
||
|
if cf.de {
|
||
|
cf.iv[15] = src[i]
|
||
|
} else {
|
||
|
cf.iv[15] = val
|
||
|
}
|
||
|
dst[i] = val
|
||
|
}
|
||
|
}
|