mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 03:47:38 +03:00
61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package shadowsocks
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"crypto/sha1"
|
|
"hash/crc32"
|
|
"io"
|
|
"math/rand"
|
|
|
|
"golang.org/x/crypto/hkdf"
|
|
"sing/common"
|
|
"sing/common/socksaddr"
|
|
)
|
|
|
|
const MaxPacketSize = 16*1024 - 1
|
|
|
|
func Kdf(key, iv []byte, keyLength int) []byte {
|
|
subKey := make([]byte, keyLength)
|
|
kdf := hkdf.New(sha1.New, key, iv, []byte("ss-subkey"))
|
|
common.Must1(io.ReadFull(kdf, subKey))
|
|
return subKey
|
|
}
|
|
|
|
func Key(password []byte, keySize int) []byte {
|
|
const md5Len = 16
|
|
|
|
cnt := (keySize-1)/md5Len + 1
|
|
m := make([]byte, cnt*md5Len)
|
|
sum := md5.Sum(password)
|
|
copy(m, sum[:])
|
|
|
|
// Repeatedly call md5 until bytes generated is enough.
|
|
// Each call to md5 uses data: prev md5 sum + password.
|
|
d := make([]byte, md5Len+len(password))
|
|
start := 0
|
|
for i := 1; i < cnt; i++ {
|
|
start += md5Len
|
|
copy(d, m[start-md5Len:start])
|
|
copy(d[md5Len:], password)
|
|
sum = md5.Sum(d)
|
|
copy(m[start:], sum[:])
|
|
}
|
|
return m[:keySize]
|
|
}
|
|
|
|
func RemapToPrintable(input []byte) {
|
|
const charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\\\""
|
|
seed := rand.New(rand.NewSource(int64(crc32.ChecksumIEEE(input))))
|
|
for i := range input {
|
|
input[i] = charSet[seed.Intn(len(charSet))]
|
|
}
|
|
}
|
|
|
|
var AddressSerializer = socksaddr.NewSerializer(
|
|
socksaddr.AddressFamilyByte(0x01, socksaddr.AddressFamilyIPv4),
|
|
socksaddr.AddressFamilyByte(0x04, socksaddr.AddressFamilyIPv6),
|
|
socksaddr.AddressFamilyByte(0x03, socksaddr.AddressFamilyFqdn),
|
|
socksaddr.WithFamilyParser(func(b byte) byte {
|
|
return b & 0x0F
|
|
}),
|
|
)
|