encrypt.go 5.1 KB

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