mirror of
https://github.com/PretendoNetwork/nex-go.git
synced 2025-04-02 11:02:14 -04:00
encryption: added QuazalRC4
This commit is contained in:
parent
9cec5d9e9c
commit
a63ca441a9
3 changed files with 95 additions and 16 deletions
95
encryption/quazal_rc4.go
Normal file
95
encryption/quazal_rc4.go
Normal file
|
@ -0,0 +1,95 @@
|
|||
package encryption
|
||||
|
||||
import (
|
||||
"crypto/rc4"
|
||||
)
|
||||
|
||||
// QuazalRC4 encrypts data with RC4. Each iteration uses a new cipher instance. The key is always CD&ML
|
||||
type QuazalRC4 struct {
|
||||
key []byte
|
||||
cipher *rc4.Cipher
|
||||
decipher *rc4.Cipher
|
||||
cipheredCount uint64
|
||||
decipheredCount uint64
|
||||
}
|
||||
|
||||
// Key returns the crypto key
|
||||
func (r *QuazalRC4) Key() []byte {
|
||||
return r.key
|
||||
}
|
||||
|
||||
// SetKey sets the crypto key and updates the ciphers
|
||||
func (r *QuazalRC4) SetKey(key []byte) error {
|
||||
r.key = key
|
||||
|
||||
cipher, err := rc4.NewCipher(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
decipher, err := rc4.NewCipher(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.cipher = cipher
|
||||
r.decipher = decipher
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encrypt encrypts the payload with the outgoing QuazalRC4 stream
|
||||
func (r *QuazalRC4) Encrypt(payload []byte) ([]byte, error) {
|
||||
r.SetKey([]byte("CD&ML"))
|
||||
|
||||
ciphered := make([]byte, len(payload))
|
||||
|
||||
r.cipher.XORKeyStream(ciphered, payload)
|
||||
|
||||
r.cipheredCount += uint64(len(payload))
|
||||
|
||||
return ciphered, nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts the payload with the incoming QuazalRC4 stream
|
||||
func (r *QuazalRC4) Decrypt(payload []byte) ([]byte, error) {
|
||||
r.SetKey([]byte("CD&ML"))
|
||||
|
||||
deciphered := make([]byte, len(payload))
|
||||
|
||||
r.decipher.XORKeyStream(deciphered, payload)
|
||||
|
||||
r.decipheredCount += uint64(len(payload))
|
||||
|
||||
return deciphered, nil
|
||||
}
|
||||
|
||||
// Copy returns a copy of the algorithm while retaining it's state
|
||||
func (r *QuazalRC4) Copy() Algorithm {
|
||||
copied := NewQuazalRC4Encryption()
|
||||
|
||||
copied.SetKey(r.key)
|
||||
|
||||
// * crypto/rc4 does not expose a way to directly copy streams and retain their state.
|
||||
// * This just discards the number of iterations done in the original ciphers to sync
|
||||
// * the copied ciphers states to the original
|
||||
for i := 0; i < int(r.cipheredCount); i++ {
|
||||
copied.cipher.XORKeyStream([]byte{0}, []byte{0})
|
||||
}
|
||||
|
||||
for i := 0; i < int(r.decipheredCount); i++ {
|
||||
copied.decipher.XORKeyStream([]byte{0}, []byte{0})
|
||||
}
|
||||
|
||||
copied.cipheredCount = r.cipheredCount
|
||||
copied.decipheredCount = r.decipheredCount
|
||||
|
||||
return copied
|
||||
}
|
||||
|
||||
// NewQuazalRC4Encryption returns a new instance of the QuazalRC4 encryption
|
||||
func NewQuazalRC4Encryption() *QuazalRC4 {
|
||||
return &QuazalRC4{
|
||||
key: make([]byte, 0),
|
||||
}
|
||||
}
|
|
@ -148,14 +148,6 @@ func (p *PRUDPPacket) decryptPayload() []byte {
|
|||
if p.packetType == DataPacket {
|
||||
slidingWindow := p.sender.SlidingWindow(p.SubstreamID())
|
||||
|
||||
// * According to other Quazal server implementations,
|
||||
// * the RC4 stream is always reset to the default key
|
||||
// * regardless if the client is connecting to a secure
|
||||
// * server (prudps) or not
|
||||
if p.version == 0 && p.sender.Endpoint.Server.PRUDPV0Settings.IsQuazalMode {
|
||||
slidingWindow.SetCipherKey([]byte("CD&ML"))
|
||||
}
|
||||
|
||||
payload, _ = slidingWindow.streamSettings.EncryptionAlgorithm.Decrypt(payload)
|
||||
}
|
||||
|
||||
|
|
|
@ -268,14 +268,6 @@ func (s *PRUDPServer) sendPacket(packet PRUDPPacketInterface) {
|
|||
logger.Error(err.Error())
|
||||
}
|
||||
|
||||
// * According to other Quazal server implementations,
|
||||
// * the RC4 stream is always reset to the default key
|
||||
// * regardless if the client is connecting to a secure
|
||||
// * server (prudps) or not
|
||||
if packet.Version() == 0 && s.PRUDPV0Settings.IsQuazalMode {
|
||||
slidingWindow.SetCipherKey([]byte("CD&ML"))
|
||||
}
|
||||
|
||||
encryptedPayload, err := slidingWindow.streamSettings.EncryptionAlgorithm.Encrypt(compressedPayload)
|
||||
if err != nil {
|
||||
logger.Error(err.Error())
|
||||
|
|
Loading…
Add table
Reference in a new issue