encrypt.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package aead
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/hmac"
  7. "crypto/rand"
  8. "encoding/binary"
  9. "errors"
  10. "io"
  11. "time"
  12. "v2ray.com/core/common"
  13. )
  14. func SealVMessAEADHeader(key [16]byte, data []byte) []byte {
  15. generatedAuthID := CreateAuthID(key[:], time.Now().Unix())
  16. connectionNonce := make([]byte, 8)
  17. if _, err := io.ReadFull(rand.Reader, connectionNonce); err != nil {
  18. panic(err.Error())
  19. }
  20. aeadPayloadLengthSerializeBuffer := bytes.NewBuffer(nil)
  21. var headerPayloadDataLen uint16
  22. headerPayloadDataLen = uint16(len(data))
  23. common.Must(binary.Write(aeadPayloadLengthSerializeBuffer, binary.BigEndian, headerPayloadDataLen))
  24. authidCheckValue := KDF16(key[:], KDFSaltConst_VmessAuthIDCheckValue, string(generatedAuthID[:]), string(aeadPayloadLengthSerializeBuffer.Bytes()), string(connectionNonce))
  25. aeadPayloadLengthSerializedByte := aeadPayloadLengthSerializeBuffer.Bytes()
  26. aeadPayloadLengthMask := KDF16(key[:], KDFSaltConst_VMessLengthMask, string(generatedAuthID[:]), string(connectionNonce[:]))[:2]
  27. aeadPayloadLengthSerializedByte[0] = aeadPayloadLengthSerializedByte[0] ^ aeadPayloadLengthMask[0]
  28. aeadPayloadLengthSerializedByte[1] = aeadPayloadLengthSerializedByte[1] ^ aeadPayloadLengthMask[1]
  29. payloadHeaderAEADKey := KDF16(key[:], KDFSaltConst_VMessHeaderPayloadAEADKey, string(generatedAuthID[:]), string(connectionNonce))
  30. payloadHeaderAEADNonce := KDF(key[:], KDFSaltConst_VMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
  31. payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey)
  32. if err != nil {
  33. panic(err.Error())
  34. }
  35. payloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)
  36. if err != nil {
  37. panic(err.Error())
  38. }
  39. payloadHeaderAEADEncrypted := payloadHeaderAEAD.Seal(nil, payloadHeaderAEADNonce, data, generatedAuthID[:])
  40. var outputBuffer = bytes.NewBuffer(nil)
  41. common.Must2(outputBuffer.Write(generatedAuthID[:])) //16
  42. common.Must2(outputBuffer.Write(authidCheckValue)) //16
  43. common.Must2(outputBuffer.Write(aeadPayloadLengthSerializedByte)) //2
  44. common.Must2(outputBuffer.Write(connectionNonce)) //8
  45. common.Must2(outputBuffer.Write(payloadHeaderAEADEncrypted))
  46. return outputBuffer.Bytes()
  47. }
  48. func OpenVMessAEADHeader(key [16]byte, authid [16]byte, data io.Reader) ([]byte, bool, error, int) {
  49. var authidCheckValue [16]byte
  50. var headerPayloadDataLen [2]byte
  51. var nonce [8]byte
  52. authidCheckValueReadBytesCounts, err := io.ReadFull(data, authidCheckValue[:])
  53. if err != nil {
  54. return nil, false, err, authidCheckValueReadBytesCounts
  55. }
  56. headerPayloadDataLenReadBytesCounts, err := io.ReadFull(data, headerPayloadDataLen[:])
  57. if err != nil {
  58. return nil, false, err, authidCheckValueReadBytesCounts + headerPayloadDataLenReadBytesCounts
  59. }
  60. nonceReadBytesCounts, err := io.ReadFull(data, nonce[:])
  61. if err != nil {
  62. return nil, false, err, authidCheckValueReadBytesCounts + headerPayloadDataLenReadBytesCounts + nonceReadBytesCounts
  63. }
  64. //Unmask Length
  65. LengthMask := KDF16(key[:], KDFSaltConst_VMessLengthMask, string(authid[:]), string(nonce[:]))[:2]
  66. headerPayloadDataLen[0] = headerPayloadDataLen[0] ^ LengthMask[0]
  67. headerPayloadDataLen[1] = headerPayloadDataLen[1] ^ LengthMask[1]
  68. authidCheckValueReceivedFromNetwork := KDF16(key[:], KDFSaltConst_VmessAuthIDCheckValue, string(authid[:]), string(headerPayloadDataLen[:]), string(nonce[:]))
  69. if !hmac.Equal(authidCheckValueReceivedFromNetwork, authidCheckValue[:]) {
  70. return nil, true, errCheckMismatch, authidCheckValueReadBytesCounts + headerPayloadDataLenReadBytesCounts + nonceReadBytesCounts
  71. }
  72. var length uint16
  73. common.Must(binary.Read(bytes.NewReader(headerPayloadDataLen[:]), binary.BigEndian, &length))
  74. payloadHeaderAEADKey := KDF16(key[:], KDFSaltConst_VMessHeaderPayloadAEADKey, string(authid[:]), string(nonce[:]))
  75. payloadHeaderAEADNonce := KDF(key[:], KDFSaltConst_VMessHeaderPayloadAEADIV, string(authid[:]), string(nonce[:]))[:12]
  76. //16 == AEAD Tag size
  77. payloadHeaderAEADEncrypted := make([]byte, length+16)
  78. payloadHeaderAEADEncryptedReadedBytesCounts, err := io.ReadFull(data, payloadHeaderAEADEncrypted)
  79. if err != nil {
  80. return nil, false, err, authidCheckValueReadBytesCounts + headerPayloadDataLenReadBytesCounts + payloadHeaderAEADEncryptedReadedBytesCounts + nonceReadBytesCounts
  81. }
  82. payloadHeaderAEADAESBlock, err := aes.NewCipher(payloadHeaderAEADKey)
  83. if err != nil {
  84. panic(err.Error())
  85. }
  86. payloadHeaderAEAD, err := cipher.NewGCM(payloadHeaderAEADAESBlock)
  87. if err != nil {
  88. panic(err.Error())
  89. }
  90. out, erropenAEAD := payloadHeaderAEAD.Open(nil, payloadHeaderAEADNonce, payloadHeaderAEADEncrypted, authid[:])
  91. if erropenAEAD != nil {
  92. return nil, true, erropenAEAD, authidCheckValueReadBytesCounts + headerPayloadDataLenReadBytesCounts + payloadHeaderAEADEncryptedReadedBytesCounts + nonceReadBytesCounts
  93. }
  94. return out, false, nil, authidCheckValueReadBytesCounts + headerPayloadDataLenReadBytesCounts + payloadHeaderAEADEncryptedReadedBytesCounts + nonceReadBytesCounts
  95. }
  96. var errCheckMismatch = errors.New("check verify failed")