encrypt.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package aead
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "encoding/binary"
  6. "io"
  7. "time"
  8. "github.com/xtls/xray-core/common"
  9. "github.com/xtls/xray-core/common/crypto"
  10. )
  11. func SealVMessAEADHeader(key [16]byte, data []byte) []byte {
  12. generatedAuthID := CreateAuthID(key[:], time.Now().Unix())
  13. connectionNonce := make([]byte, 8)
  14. if _, err := io.ReadFull(rand.Reader, connectionNonce); err != nil {
  15. panic(err.Error())
  16. }
  17. aeadPayloadLengthSerializeBuffer := bytes.NewBuffer(nil)
  18. headerPayloadDataLen := uint16(len(data))
  19. common.Must(binary.Write(aeadPayloadLengthSerializeBuffer, binary.BigEndian, headerPayloadDataLen))
  20. aeadPayloadLengthSerializedByte := aeadPayloadLengthSerializeBuffer.Bytes()
  21. var payloadHeaderLengthAEADEncrypted []byte
  22. {
  23. payloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADKey, string(generatedAuthID[:]), string(connectionNonce))
  24. payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
  25. payloadHeaderAEAD := crypto.NewAesGcm(payloadHeaderLengthAEADKey)
  26. payloadHeaderLengthAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderLengthAEADNonce, aeadPayloadLengthSerializedByte, generatedAuthID[:])
  27. }
  28. var payloadHeaderAEADEncrypted []byte
  29. {
  30. payloadHeaderAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadAEADKey, string(generatedAuthID[:]), string(connectionNonce))
  31. payloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
  32. payloadHeaderAEAD := crypto.NewAesGcm(payloadHeaderAEADKey)
  33. payloadHeaderAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderAEADNonce, data, generatedAuthID[:])
  34. }
  35. outputBuffer := bytes.NewBuffer(nil)
  36. common.Must2(outputBuffer.Write(generatedAuthID[:])) // 16
  37. common.Must2(outputBuffer.Write(payloadHeaderLengthAEADEncrypted)) // 2+16
  38. common.Must2(outputBuffer.Write(connectionNonce)) // 8
  39. common.Must2(outputBuffer.Write(payloadHeaderAEADEncrypted))
  40. return outputBuffer.Bytes()
  41. }
  42. func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, bool, int, error) {
  43. var payloadHeaderLengthAEADEncrypted [18]byte
  44. var nonce [8]byte
  45. var bytesRead int
  46. authidCheckValueReadBytesCounts, err := io.ReadFull(data, payloadHeaderLengthAEADEncrypted[:])
  47. bytesRead += authidCheckValueReadBytesCounts
  48. if err != nil {
  49. return nil, false, bytesRead, err
  50. }
  51. nonceReadBytesCounts, err := io.ReadFull(data, nonce[:])
  52. bytesRead += nonceReadBytesCounts
  53. if err != nil {
  54. return nil, false, bytesRead, err
  55. }
  56. // Decrypt Length
  57. var decryptedAEADHeaderLengthPayloadResult []byte
  58. {
  59. payloadHeaderLengthAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADKey, string(authid[:]), string(nonce[:]))
  60. payloadHeaderLengthAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadLengthAEADIV, string(authid[:]), string(nonce[:]))[:12]
  61. payloadHeaderLengthAEAD := crypto.NewAesGcm(payloadHeaderLengthAEADKey)
  62. decryptedAEADHeaderLengthPayload, erropenAEAD := payloadHeaderLengthAEAD.Open(nil, payloadHeaderLengthAEADNonce, payloadHeaderLengthAEADEncrypted[:], authid[:])
  63. if erropenAEAD != nil {
  64. return nil, true, bytesRead, erropenAEAD
  65. }
  66. decryptedAEADHeaderLengthPayloadResult = decryptedAEADHeaderLengthPayload
  67. }
  68. var length uint16
  69. common.Must(binary.Read(bytes.NewReader(decryptedAEADHeaderLengthPayloadResult), binary.BigEndian, &length))
  70. var decryptedAEADHeaderPayloadR []byte
  71. var payloadHeaderAEADEncryptedReadedBytesCounts int
  72. {
  73. payloadHeaderAEADKey := KDF16(key[:], KDFSaltConstVMessHeaderPayloadAEADKey, string(authid[:]), string(nonce[:]))
  74. payloadHeaderAEADNonce := KDF(key[:], KDFSaltConstVMessHeaderPayloadAEADIV, string(authid[:]), string(nonce[:]))[:12]
  75. // 16 == AEAD Tag size
  76. payloadHeaderAEADEncrypted := make([]byte, length+16)
  77. payloadHeaderAEADEncryptedReadedBytesCounts, err = io.ReadFull(data, payloadHeaderAEADEncrypted)
  78. bytesRead += payloadHeaderAEADEncryptedReadedBytesCounts
  79. if err != nil {
  80. return nil, false, bytesRead, err
  81. }
  82. payloadHeaderAEAD := crypto.NewAesGcm(payloadHeaderAEADKey)
  83. decryptedAEADHeaderPayload, erropenAEAD := payloadHeaderAEAD.Open(nil, payloadHeaderAEADNonce, payloadHeaderAEADEncrypted, authid[:])
  84. if erropenAEAD != nil {
  85. return nil, true, bytesRead, erropenAEAD
  86. }
  87. decryptedAEADHeaderPayloadR = decryptedAEADHeaderPayload
  88. }
  89. return decryptedAEADHeaderPayloadR, false, bytesRead, nil
  90. }