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  })