| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package shadowsocks2022
- import (
- "crypto/subtle"
- "io"
- "github.com/lunixbochs/struc"
- "github.com/v2fly/v2ray-core/v5/common/buf"
- "lukechampine.com/blake3"
- )
- func newAESEIH(size int) *aesEIH {
- return &aesEIH{length: size}
- }
- func newAESEIHWithData(size int, eih [][aesEIHSize]byte) *aesEIH {
- return &aesEIH{length: size, eih: eih}
- }
- const aesEIHSize = 16
- type aesEIH struct {
- eih [][aesEIHSize]byte
- length int
- }
- func (a *aesEIH) Pack(p []byte, opt *struc.Options) (int, error) {
- var totalCopy int
- for i := 0; i < a.length; i++ {
- n := copy(p[aesEIHSize*i:aesEIHSize*(i+1)], a.eih[i][:])
- if n != 16 {
- return 0, newError("failed to pack aesEIH")
- }
- totalCopy += n
- }
- return totalCopy, nil
- }
- func (a *aesEIH) Unpack(r io.Reader, length int, opt *struc.Options) error {
- a.eih = make([][aesEIHSize]byte, a.length)
- for i := 0; i < a.length; i++ {
- n, err := r.Read(a.eih[i][:])
- if err != nil {
- return newError("failed to unpack aesEIH").Base(err)
- }
- if n != aesEIHSize {
- return newError("failed to unpack aesEIH")
- }
- }
- return nil
- }
- func (a *aesEIH) Size(opt *struc.Options) int {
- return a.length * aesEIHSize
- }
- func (a *aesEIH) String() string {
- return ""
- }
- const aesEIHPskHashSize = 16
- type aesEIHGenerator struct {
- ipsk [][]byte
- ipskHash [][aesEIHPskHashSize]byte
- psk []byte
- pskHash [aesEIHPskHashSize]byte
- length int
- }
- func newAESEIHGeneratorContainer(size int, effectivePsk []byte, ipsk [][]byte) *aesEIHGenerator {
- var ipskHash [][aesEIHPskHashSize]byte
- for _, v := range ipsk {
- hash := blake3.Sum512(v)
- ipskHash = append(ipskHash, [aesEIHPskHashSize]byte(hash[:16]))
- }
- pskHashFull := blake3.Sum512(effectivePsk)
- pskHash := [aesEIHPskHashSize]byte(pskHashFull[:16])
- return &aesEIHGenerator{length: size, ipsk: ipsk, ipskHash: ipskHash, psk: effectivePsk, pskHash: pskHash}
- }
- func (a *aesEIHGenerator) GenerateEIH(derivation KeyDerivation, method Method, salt []byte) (ExtensibleIdentityHeaders, error) {
- return a.generateEIHWithMask(derivation, method, salt, nil)
- }
- func (a *aesEIHGenerator) GenerateEIHUDP(derivation KeyDerivation, method Method, mask []byte) (ExtensibleIdentityHeaders, error) {
- return a.generateEIHWithMask(derivation, method, nil, mask)
- }
- func (a *aesEIHGenerator) generateEIHWithMask(derivation KeyDerivation, method Method, salt, mask []byte) (ExtensibleIdentityHeaders, error) {
- eih := make([][16]byte, a.length)
- current := a.length - 1
- currentPskHash := a.pskHash
- for {
- identityKeyBuf := buf.New()
- identityKey := identityKeyBuf.Extend(int32(method.GetSessionSubKeyAndSaltLength()))
- if mask == nil {
- err := derivation.GetIdentitySubKey(a.ipsk[current], salt, identityKey)
- if err != nil {
- return nil, newError("failed to get identity sub key").Base(err)
- }
- } else {
- copy(identityKey, a.ipsk[current])
- }
- eih[current] = [16]byte{}
- if mask != nil {
- subtle.XORBytes(currentPskHash[:], mask, currentPskHash[:])
- }
- err := method.GenerateEIH(identityKey, currentPskHash[:], eih[current][:])
- if err != nil {
- return nil, newError("failed to generate EIH").Base(err)
- }
- current--
- if current < 0 {
- break
- }
- currentPskHash = a.ipskHash[current]
- identityKeyBuf.Release()
- }
- return newAESEIHWithData(a.length, eih), nil
- }
|