1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package aes
6
7import (
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.)
15func 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
29func 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.
52func 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.
75func 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.)
88func 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.)
106func 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//	http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
126
127// Appendix A of FIPS 197: Key expansion examples
128type KeyTest struct {
129	key []byte
130	enc []uint32
131	dec []uint32 // decryption expansion; not in FIPS 197, computed from C implementation.
132}
133
134var 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,
143			0xef44a541, 0xa8525b7f, 0xb671253b, 0xdb0bad00,
144			0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc,
145			0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd,
146			0x4e54f70e, 0x5f5fc9f3, 0x84a64fb2, 0x4ea6dc4f,
147			0xead27321, 0xb58dbad2, 0x312bf560, 0x7f8d292f,
148			0xac7766f3, 0x19fadc21, 0x28d12941, 0x575c006e,
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,
173			0x62f8ead2, 0x522c6b7b, 0xfe0c91f7, 0x2402f5a5,
174			0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2,
175			0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd,
176			0xe75fad44, 0xbb095386, 0x485af057, 0x21efb14f,
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,
182			0xa7e1466c, 0x9411f1df, 0x821f750a, 0xad07d753,
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,
201			0x812c81ad, 0xdadf48ba, 0x24360af2, 0xfab8b464,
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,
208			0xcafaaae3, 0xe4d59b34, 0x9adf6ace, 0xbd10190d,
209			0xfe4890d1, 0xe6188d0b, 0x046df344, 0x706c631e,
210		},
211		nil,
212	},
213}
214
215// Test key expansion against FIPS 197 examples.
216func TestExpandKey(t *testing.T) {
217L:
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		if dec != nil {
235			for j, v := range dec {
236				if v != tt.dec[j] {
237					t.Errorf("key %d: dec[%d] = %#x, want %#x", i, j, v, tt.dec[j])
238					continue L
239				}
240			}
241		}
242	}
243}
244
245// Appendix B, C of FIPS 197: Cipher examples, Example vectors.
246type CryptTest struct {
247	key []byte
248	in  []byte
249	out []byte
250}
251
252var encryptTests = []CryptTest{
253	{
254		// Appendix B.
255		[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
256		[]byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34},
257		[]byte{0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32},
258	},
259	{
260		// Appendix C.1.  AES-128
261		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
262		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
263		[]byte{0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a},
264	},
265	{
266		// Appendix C.2.  AES-192
267		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
268			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
269		},
270		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
271		[]byte{0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91},
272	},
273	{
274		// Appendix C.3.  AES-256
275		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
276			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
277		},
278		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
279		[]byte{0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89},
280	},
281}
282
283// Test Cipher Encrypt method against FIPS 197 examples.
284func TestCipherEncrypt(t *testing.T) {
285	for i, tt := range encryptTests {
286		c, err := NewCipher(tt.key)
287		if err != nil {
288			t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
289			continue
290		}
291		out := make([]byte, len(tt.in))
292		c.Encrypt(out, tt.in)
293		for j, v := range out {
294			if v != tt.out[j] {
295				t.Errorf("Cipher.Encrypt %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
296				break
297			}
298		}
299	}
300}
301
302// Test Cipher Decrypt against FIPS 197 examples.
303func TestCipherDecrypt(t *testing.T) {
304	for i, tt := range encryptTests {
305		c, err := NewCipher(tt.key)
306		if err != nil {
307			t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
308			continue
309		}
310		plain := make([]byte, len(tt.in))
311		c.Decrypt(plain, tt.out)
312		for j, v := range plain {
313			if v != tt.in[j] {
314				t.Errorf("decryptBlock %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
315				break
316			}
317		}
318	}
319}
320
321// Test short input/output.
322// Assembly used to not notice.
323// See issue 7928.
324func TestShortBlocks(t *testing.T) {
325	bytes := func(n int) []byte { return make([]byte, n) }
326
327	c, _ := NewCipher(bytes(16))
328
329	mustPanic(t, "crypto/aes: input not full block", func() { c.Encrypt(bytes(1), bytes(1)) })
330	mustPanic(t, "crypto/aes: input not full block", func() { c.Decrypt(bytes(1), bytes(1)) })
331	mustPanic(t, "crypto/aes: input not full block", func() { c.Encrypt(bytes(100), bytes(1)) })
332	mustPanic(t, "crypto/aes: input not full block", func() { c.Decrypt(bytes(100), bytes(1)) })
333	mustPanic(t, "crypto/aes: output not full block", func() { c.Encrypt(bytes(1), bytes(100)) })
334	mustPanic(t, "crypto/aes: output not full block", func() { c.Decrypt(bytes(1), bytes(100)) })
335}
336
337func mustPanic(t *testing.T, msg string, f func()) {
338	defer func() {
339		err := recover()
340		if err == nil {
341			t.Errorf("function did not panic, wanted %q", msg)
342		} else if err != msg {
343			t.Errorf("got panic %v, wanted %q", err, msg)
344		}
345	}()
346	f()
347}
348
349func BenchmarkEncrypt(b *testing.B) {
350	tt := encryptTests[0]
351	c, err := NewCipher(tt.key)
352	if err != nil {
353		b.Fatal("NewCipher:", err)
354	}
355	out := make([]byte, len(tt.in))
356	b.SetBytes(int64(len(out)))
357	b.ResetTimer()
358	for i := 0; i < b.N; i++ {
359		c.Encrypt(out, tt.in)
360	}
361}
362
363func BenchmarkDecrypt(b *testing.B) {
364	tt := encryptTests[0]
365	c, err := NewCipher(tt.key)
366	if err != nil {
367		b.Fatal("NewCipher:", err)
368	}
369	out := make([]byte, len(tt.out))
370	b.SetBytes(int64(len(out)))
371	b.ResetTimer()
372	for i := 0; i < b.N; i++ {
373		c.Decrypt(out, tt.out)
374	}
375}
376
377func BenchmarkExpand(b *testing.B) {
378	tt := encryptTests[0]
379	n := len(tt.key) + 28
380	c := &aesCipher{make([]uint32, n), make([]uint32, n)}
381	b.ResetTimer()
382	for i := 0; i < b.N; i++ {
383		expandKey(tt.key, c.enc, c.dec)
384	}
385}
386