encrypt.go 5.1 KB

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