github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/internal/handshake/aead_test.go (about) 1 package handshake 2 3 import ( 4 "bytes" 5 "crypto/aes" 6 "crypto/cipher" 7 "crypto/rand" 8 "crypto/tls" 9 "fmt" 10 11 "github.com/apernet/quic-go/internal/protocol" 12 13 . "github.com/onsi/ginkgo/v2" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Long Header AEAD", func() { 18 for _, ver := range []protocol.Version{protocol.Version1, protocol.Version2} { 19 v := ver 20 21 Context(fmt.Sprintf("using version %s", v), func() { 22 for i := range cipherSuites { 23 cs := cipherSuites[i] 24 25 Context(fmt.Sprintf("using %s", tls.CipherSuiteName(cs.ID)), func() { 26 getSealerAndOpener := func() (LongHeaderSealer, LongHeaderOpener) { 27 key := make([]byte, 16) 28 hpKey := make([]byte, 16) 29 rand.Read(key) 30 rand.Read(hpKey) 31 block, err := aes.NewCipher(key) 32 Expect(err).ToNot(HaveOccurred()) 33 aead, err := cipher.NewGCM(block) 34 Expect(err).ToNot(HaveOccurred()) 35 36 return newLongHeaderSealer(&xorNonceAEAD{aead: aead}, newHeaderProtector(cs, hpKey, true, v)), 37 newLongHeaderOpener(&xorNonceAEAD{aead: aead}, newHeaderProtector(cs, hpKey, true, v)) 38 } 39 40 Context("message encryption", func() { 41 msg := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") 42 ad := []byte("Donec in velit neque.") 43 44 It("encrypts and decrypts a message", func() { 45 sealer, opener := getSealerAndOpener() 46 encrypted := sealer.Seal(nil, msg, 0x1337, ad) 47 opened, err := opener.Open(nil, encrypted, 0x1337, ad) 48 Expect(err).ToNot(HaveOccurred()) 49 Expect(opened).To(Equal(msg)) 50 }) 51 52 It("fails to open a message if the associated data is not the same", func() { 53 sealer, opener := getSealerAndOpener() 54 encrypted := sealer.Seal(nil, msg, 0x1337, ad) 55 _, err := opener.Open(nil, encrypted, 0x1337, []byte("wrong ad")) 56 Expect(err).To(MatchError(ErrDecryptionFailed)) 57 }) 58 59 It("fails to open a message if the packet number is not the same", func() { 60 sealer, opener := getSealerAndOpener() 61 encrypted := sealer.Seal(nil, msg, 0x1337, ad) 62 _, err := opener.Open(nil, encrypted, 0x42, ad) 63 Expect(err).To(MatchError(ErrDecryptionFailed)) 64 }) 65 66 It("decodes the packet number", func() { 67 sealer, opener := getSealerAndOpener() 68 encrypted := sealer.Seal(nil, msg, 0x1337, ad) 69 _, err := opener.Open(nil, encrypted, 0x1337, ad) 70 Expect(err).ToNot(HaveOccurred()) 71 Expect(opener.DecodePacketNumber(0x38, protocol.PacketNumberLen1)).To(BeEquivalentTo(0x1338)) 72 }) 73 74 It("ignores packets it can't decrypt for packet number derivation", func() { 75 sealer, opener := getSealerAndOpener() 76 encrypted := sealer.Seal(nil, msg, 0x1337, ad) 77 _, err := opener.Open(nil, encrypted[:len(encrypted)-1], 0x1337, ad) 78 Expect(err).To(HaveOccurred()) 79 Expect(opener.DecodePacketNumber(0x38, protocol.PacketNumberLen1)).To(BeEquivalentTo(0x38)) 80 }) 81 }) 82 83 Context("header encryption", func() { 84 It("encrypts and encrypts the header", func() { 85 sealer, opener := getSealerAndOpener() 86 var lastFourBitsDifferent int 87 for i := 0; i < 100; i++ { 88 sample := make([]byte, 16) 89 rand.Read(sample) 90 header := []byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef} 91 sealer.EncryptHeader(sample, &header[0], header[9:13]) 92 if header[0]&0xf != 0xb5&0xf { 93 lastFourBitsDifferent++ 94 } 95 Expect(header[0] & 0xf0).To(Equal(byte(0xb5 & 0xf0))) 96 Expect(header[1:9]).To(Equal([]byte{1, 2, 3, 4, 5, 6, 7, 8})) 97 Expect(header[9:13]).ToNot(Equal([]byte{0xde, 0xad, 0xbe, 0xef})) 98 opener.DecryptHeader(sample, &header[0], header[9:13]) 99 Expect(header).To(Equal([]byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef})) 100 } 101 Expect(lastFourBitsDifferent).To(BeNumerically(">", 75)) 102 }) 103 104 It("encrypts and encrypts the header, for a 0xfff..fff sample", func() { 105 sealer, opener := getSealerAndOpener() 106 var lastFourBitsDifferent int 107 for i := 0; i < 100; i++ { 108 sample := bytes.Repeat([]byte{0xff}, 16) 109 header := []byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef} 110 sealer.EncryptHeader(sample, &header[0], header[9:13]) 111 if header[0]&0xf != 0xb5&0xf { 112 lastFourBitsDifferent++ 113 } 114 Expect(header[0] & 0xf0).To(Equal(byte(0xb5 & 0xf0))) 115 Expect(header[1:9]).To(Equal([]byte{1, 2, 3, 4, 5, 6, 7, 8})) 116 Expect(header[9:13]).ToNot(Equal([]byte{0xde, 0xad, 0xbe, 0xef})) 117 opener.DecryptHeader(sample, &header[0], header[9:13]) 118 Expect(header).To(Equal([]byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef})) 119 } 120 }) 121 122 It("fails to decrypt the header when using a different sample", func() { 123 sealer, opener := getSealerAndOpener() 124 header := []byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef} 125 sample := make([]byte, 16) 126 rand.Read(sample) 127 sealer.EncryptHeader(sample, &header[0], header[9:13]) 128 rand.Read(sample) // use a different sample 129 opener.DecryptHeader(sample, &header[0], header[9:13]) 130 Expect(header).ToNot(Equal([]byte{0xb5, 1, 2, 3, 4, 5, 6, 7, 8, 0xde, 0xad, 0xbe, 0xef})) 131 }) 132 }) 133 }) 134 } 135 }) 136 } 137 })