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