# Source file src/crypto/aes/aes_test.go

```     1  // Copyright 2009 The Go Authors. All rights reserved.
2  // Use of this source code is governed by a BSD-style
4
5  package aes
6
7  import (
8  	"testing"
9  )
10
11  // See const.go for overview of math here.
12
13  // Test that powx is initialized correctly.
14  // (Can adapt this code to generate it too.)
15  func TestPowx(t *testing.T) {
16  	p := 1
17  	for i := 0; i < len(powx); i++ {
18  		if powx[i] != byte(p) {
19  			t.Errorf("powx[%d] = %#x, want %#x", i, powx[i], p)
20  		}
21  		p <<= 1
22  		if p&0x100 != 0 {
23  			p ^= poly
24  		}
25  	}
26  }
27
28  // Multiply b and c as GF(2) polynomials modulo poly
29  func mul(b, c uint32) uint32 {
30  	i := b
31  	j := c
32  	s := uint32(0)
33  	for k := uint32(1); k < 0x100 && j != 0; k <<= 1 {
34  		// Invariant: k == 1<<n, i == b * xⁿ
35
36  		if j&k != 0 {
37  			// s += i in GF(2); xor in binary
38  			s ^= i
39  			j ^= k // turn off bit to end loop early
40  		}
41
42  		// i *= x in GF(2) modulo the polynomial
43  		i <<= 1
44  		if i&0x100 != 0 {
45  			i ^= poly
46  		}
47  	}
48  	return s
49  }
50
51  // Test all mul inputs against bit-by-bit n² algorithm.
52  func TestMul(t *testing.T) {
53  	for i := uint32(0); i < 256; i++ {
54  		for j := uint32(0); j < 256; j++ {
55  			// Multiply i, j bit by bit.
56  			s := uint8(0)
57  			for k := uint(0); k < 8; k++ {
58  				for l := uint(0); l < 8; l++ {
59  					if i&(1<<k) != 0 && j&(1<<l) != 0 {
60  						s ^= powx[k+l]
61  					}
62  				}
63  			}
64  			if x := mul(i, j); x != uint32(s) {
65  				t.Fatalf("mul(%#x, %#x) = %#x, want %#x", i, j, x, s)
66  			}
67  		}
68  	}
69  }
70
71  // Check that S-boxes are inverses of each other.
72  // They have more structure that we could test,
73  // but if this sanity check passes, we'll assume
74  // the cut and paste from the FIPS PDF worked.
75  func TestSboxes(t *testing.T) {
76  	for i := 0; i < 256; i++ {
77  		if j := sbox0[sbox1[i]]; j != byte(i) {
78  			t.Errorf("sbox0[sbox1[%#x]] = %#x", i, j)
79  		}
80  		if j := sbox1[sbox0[i]]; j != byte(i) {
81  			t.Errorf("sbox1[sbox0[%#x]] = %#x", i, j)
82  		}
83  	}
84  }
85
86  // Test that encryption tables are correct.
87  // (Can adapt this code to generate them too.)
88  func TestTe(t *testing.T) {
89  	for i := 0; i < 256; i++ {
90  		s := uint32(sbox0[i])
91  		s2 := mul(s, 2)
92  		s3 := mul(s, 3)
93  		w := s2<<24 | s<<16 | s<<8 | s3
94  		te := [][256]uint32{te0, te1, te2, te3}
95  		for j := 0; j < 4; j++ {
96  			if x := te[j][i]; x != w {
97  				t.Fatalf("te[%d][%d] = %#x, want %#x", j, i, x, w)
98  			}
99  			w = w<<24 | w>>8
100  		}
101  	}
102  }
103
104  // Test that decryption tables are correct.
105  // (Can adapt this code to generate them too.)
106  func TestTd(t *testing.T) {
107  	for i := 0; i < 256; i++ {
108  		s := uint32(sbox1[i])
109  		s9 := mul(s, 0x9)
110  		sb := mul(s, 0xb)
111  		sd := mul(s, 0xd)
112  		se := mul(s, 0xe)
113  		w := se<<24 | s9<<16 | sd<<8 | sb
114  		td := [][256]uint32{td0, td1, td2, td3}
115  		for j := 0; j < 4; j++ {
116  			if x := td[j][i]; x != w {
117  				t.Fatalf("td[%d][%d] = %#x, want %#x", j, i, x, w)
118  			}
119  			w = w<<24 | w>>8
120  		}
121  	}
122  }
123
124  // Test vectors are from FIPS 197:
125  //	https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
126
127  // Appendix A of FIPS 197: Key expansion examples
128  type KeyTest struct {
129  	key []byte
130  	enc []uint32
131  	dec []uint32 // decryption expansion; not in FIPS 197, computed from C implementation.
132  }
133
134  var keyTests = []KeyTest{
135  	{
136  		// A.1.  Expansion of a 128-bit Cipher Key
137  		[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
138  		[]uint32{
139  			0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c,
140  			0xa0fafe17, 0x88542cb1, 0x23a33939, 0x2a6c7605,
141  			0xf2c295f2, 0x7a96b943, 0x5935807a, 0x7359f67f,
142  			0x3d80477d, 0x4716fe3e, 0x1e237e44, 0x6d7a883b,
144  			0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc,
145  			0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd,
146  			0x4e54f70e, 0x5f5fc9f3, 0x84a64fb2, 0x4ea6dc4f,
149  			0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6,
150  		},
151  		[]uint32{
152  			0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6,
153  			0xc7b5a63, 0x1319eafe, 0xb0398890, 0x664cfbb4,
154  			0xdf7d925a, 0x1f62b09d, 0xa320626e, 0xd6757324,
155  			0x12c07647, 0xc01f22c7, 0xbc42d2f3, 0x7555114a,
156  			0x6efcd876, 0xd2df5480, 0x7c5df034, 0xc917c3b9,
157  			0x6ea30afc, 0xbc238cf6, 0xae82a4b4, 0xb54a338d,
158  			0x90884413, 0xd280860a, 0x12a12842, 0x1bc89739,
159  			0x7c1f13f7, 0x4208c219, 0xc021ae48, 0x969bf7b,
160  			0xcc7505eb, 0x3e17d1ee, 0x82296c51, 0xc9481133,
161  			0x2b3708a7, 0xf262d405, 0xbc3ebdbf, 0x4b617d62,
162  			0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x9cf4f3c,
163  		},
164  	},
165  	{
166  		// A.2.  Expansion of a 192-bit Cipher Key
167  		[]byte{
168  			0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
169  			0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
170  		},
171  		[]uint32{
172  			0x8e73b0f7, 0xda0e6452, 0xc810f32b, 0x809079e5,
174  			0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2,
175  			0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd,
177  			0xa448f6d9, 0x4d6dce24, 0xaa326360, 0x113b30e6,
178  			0xa25e7ed5, 0x83b1cf9a, 0x27f93943, 0x6a94f767,
179  			0xc0a69407, 0xd19da4e1, 0xec1786eb, 0x6fa64971,
180  			0x485f7032, 0x22cb8755, 0xe26d1352, 0x33f0b7b3,
181  			0x40beeb28, 0x2f18a259, 0x6747d26b, 0x458c553e,
183  			0xca400538, 0x8fcc5006, 0x282d166a, 0xbc3ce7b5,
184  			0xe98ba06f, 0x448c773c, 0x8ecc7204, 0x01002202,
185  		},
186  		nil,
187  	},
188  	{
189  		// A.3.  Expansion of a 256-bit Cipher Key
190  		[]byte{
191  			0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
192  			0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
193  		},
194  		[]uint32{
195  			0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781,
196  			0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4,
197  			0x9ba35411, 0x8e6925af, 0xa51a8b5f, 0x2067fcde,
198  			0xa8b09c1a, 0x93d194cd, 0xbe49846e, 0xb75d5b9a,
199  			0xd59aecb8, 0x5bf3c917, 0xfee94248, 0xde8ebe96,
200  			0xb5a9328a, 0x2678a647, 0x98312229, 0x2f6c79b3,
202  			0x98c5bfc9, 0xbebd198e, 0x268c3ba7, 0x09e04214,
203  			0x68007bac, 0xb2df3316, 0x96e939e4, 0x6c518d80,
204  			0xc814e204, 0x76a9fb8a, 0x5025c02d, 0x59c58239,
205  			0xde136967, 0x6ccc5a71, 0xfa256395, 0x9674ee15,
206  			0x5886ca5d, 0x2e2f31d7, 0x7e0af1fa, 0x27cf73c3,
207  			0x749c47ab, 0x18501dda, 0xe2757e4f, 0x7401905a,
209  			0xfe4890d1, 0xe6188d0b, 0x046df344, 0x706c631e,
210  		},
211  		nil,
212  	},
213  }
214
215  // Test key expansion against FIPS 197 examples.
216  func TestExpandKey(t *testing.T) {
217  L:
218  	for i, tt := range keyTests {
219  		enc := make([]uint32, len(tt.enc))
220  		var dec []uint32
221  		if tt.dec != nil {
222  			dec = make([]uint32, len(tt.dec))
223  		}
224  		// This test could only test Go version of expandKey because asm
225  		// version might use different memory layout for expanded keys
226  		// This is OK because we don't expose expanded keys to the outside
227  		expandKeyGo(tt.key, enc, dec)
228  		for j, v := range enc {
229  			if v != tt.enc[j] {
230  				t.Errorf("key %d: enc[%d] = %#x, want %#x", i, j, v, tt.enc[j])
231  				continue L
232  			}
233  		}
234  		for j, v := range dec {
235  			if v != tt.dec[j] {
236  				t.Errorf("key %d: dec[%d] = %#x, want %#x", i, j, v, tt.dec[j])
237  				continue L
238  			}
239  		}
240  	}
241  }
242
243  // Appendix B, C of FIPS 197: Cipher examples, Example vectors.
244  type CryptTest struct {
245  	key []byte
246  	in  []byte
247  	out []byte
248  }
249
250  var encryptTests = []CryptTest{
251  	{
252  		// Appendix B.
253  		[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
254  		[]byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34},
255  		[]byte{0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32},
256  	},
257  	{
258  		// Appendix C.1.  AES-128
259  		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
260  		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
261  		[]byte{0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a},
262  	},
263  	{
264  		// Appendix C.2.  AES-192
265  		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
266  			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
267  		},
268  		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
269  		[]byte{0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91},
270  	},
271  	{
272  		// Appendix C.3.  AES-256
273  		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
274  			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
275  		},
276  		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
277  		[]byte{0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89},
278  	},
279  }
280
281  // Test Cipher Encrypt method against FIPS 197 examples.
282  func TestCipherEncrypt(t *testing.T) {
283  	for i, tt := range encryptTests {
284  		c, err := NewCipher(tt.key)
285  		if err != nil {
286  			t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
287  			continue
288  		}
289  		out := make([]byte, len(tt.in))
290  		c.Encrypt(out, tt.in)
291  		for j, v := range out {
292  			if v != tt.out[j] {
293  				t.Errorf("Cipher.Encrypt %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
294  				break
295  			}
296  		}
297  	}
298  }
299
300  // Test Cipher Decrypt against FIPS 197 examples.
301  func TestCipherDecrypt(t *testing.T) {
302  	for i, tt := range encryptTests {
303  		c, err := NewCipher(tt.key)
304  		if err != nil {
305  			t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
306  			continue
307  		}
308  		plain := make([]byte, len(tt.in))
309  		c.Decrypt(plain, tt.out)
310  		for j, v := range plain {
311  			if v != tt.in[j] {
312  				t.Errorf("decryptBlock %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
313  				break
314  			}
315  		}
316  	}
317  }
318
319  // Test short input/output.
320  // Assembly used to not notice.
321  // See issue 7928.
322  func TestShortBlocks(t *testing.T) {
323  	bytes := func(n int) []byte { return make([]byte, n) }
324
325  	c, _ := NewCipher(bytes(16))
326
327  	mustPanic(t, "crypto/aes: input not full block", func() { c.Encrypt(bytes(1), bytes(1)) })
328  	mustPanic(t, "crypto/aes: input not full block", func() { c.Decrypt(bytes(1), bytes(1)) })
329  	mustPanic(t, "crypto/aes: input not full block", func() { c.Encrypt(bytes(100), bytes(1)) })
330  	mustPanic(t, "crypto/aes: input not full block", func() { c.Decrypt(bytes(100), bytes(1)) })
331  	mustPanic(t, "crypto/aes: output not full block", func() { c.Encrypt(bytes(1), bytes(100)) })
332  	mustPanic(t, "crypto/aes: output not full block", func() { c.Decrypt(bytes(1), bytes(100)) })
333  }
334
335  func mustPanic(t *testing.T, msg string, f func()) {
336  	defer func() {
337  		err := recover()
338  		if err == nil {
339  			t.Errorf("function did not panic, wanted %q", msg)
340  		} else if err != msg {
341  			t.Errorf("got panic %v, wanted %q", err, msg)
342  		}
343  	}()
344  	f()
345  }
346
347  func BenchmarkEncrypt(b *testing.B) {
348  	b.Run("AES-128", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[1]) })
349  	b.Run("AES-192", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[2]) })
350  	b.Run("AES-256", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[3]) })
351  }
352
353  func benchmarkEncrypt(b *testing.B, tt CryptTest) {
354  	c, err := NewCipher(tt.key)
355  	if err != nil {
356  		b.Fatal("NewCipher:", err)
357  	}
358  	out := make([]byte, len(tt.in))
359  	b.SetBytes(int64(len(out)))
360  	b.ResetTimer()
361  	for i := 0; i < b.N; i++ {
362  		c.Encrypt(out, tt.in)
363  	}
364  }
365
366  func BenchmarkDecrypt(b *testing.B) {
367  	b.Run("AES-128", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[1]) })
368  	b.Run("AES-192", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[2]) })
369  	b.Run("AES-256", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[3]) })
370  }
371
372  func benchmarkDecrypt(b *testing.B, tt CryptTest) {
373  	c, err := NewCipher(tt.key)
374  	if err != nil {
375  		b.Fatal("NewCipher:", err)
376  	}
377  	out := make([]byte, len(tt.out))
378  	b.SetBytes(int64(len(out)))
379  	b.ResetTimer()
380  	for i := 0; i < b.N; i++ {
381  		c.Decrypt(out, tt.out)
382  	}
383  }
384
385  func BenchmarkExpand(b *testing.B) {
386  	b.Run("AES-128", func(b *testing.B) { benchmarkExpand(b, encryptTests[1]) })
387  	b.Run("AES-192", func(b *testing.B) { benchmarkExpand(b, encryptTests[2]) })
388  	b.Run("AES-256", func(b *testing.B) { benchmarkExpand(b, encryptTests[3]) })
389  }
390
391  func benchmarkExpand(b *testing.B, tt CryptTest) {
392  	c := &aesCipher{l: uint8(len(tt.key) + 28)}
393  	b.ResetTimer()
394  	for i := 0; i < b.N; i++ {
395  		expandKey(tt.key, c.enc[:c.l], c.dec[:c.l])
396  	}
397  }
398
399  func BenchmarkCreateCipher(b *testing.B) {
400  	b.Run("AES-128", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[1]) })
401  	b.Run("AES-192", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[2]) })
402  	b.Run("AES-256", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[3]) })
403  }
404
405  func benchmarkCreateCipher(b *testing.B, tt CryptTest) {
406  	b.ReportAllocs()
407  	for i := 0; i < b.N; i++ {
408  		if _, err := NewCipher(tt.key); err != nil {
409  			b.Fatal(err)
410  		}
411  	}
412  }
413
```

View as plain text