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
     3  // license that can be found in the LICENSE file.
     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,
   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.
   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  	tt := encryptTests[0]
   349  	c, err := NewCipher(tt.key)
   350  	if err != nil {
   351  		b.Fatal("NewCipher:", err)
   352  	}
   353  	out := make([]byte, len(tt.in))
   354  	b.SetBytes(int64(len(out)))
   355  	b.ResetTimer()
   356  	for i := 0; i < b.N; i++ {
   357  		c.Encrypt(out, tt.in)
   358  	}
   359  }
   360  
   361  func BenchmarkDecrypt(b *testing.B) {
   362  	tt := encryptTests[0]
   363  	c, err := NewCipher(tt.key)
   364  	if err != nil {
   365  		b.Fatal("NewCipher:", err)
   366  	}
   367  	out := make([]byte, len(tt.out))
   368  	b.SetBytes(int64(len(out)))
   369  	b.ResetTimer()
   370  	for i := 0; i < b.N; i++ {
   371  		c.Decrypt(out, tt.out)
   372  	}
   373  }
   374  
   375  func BenchmarkExpand(b *testing.B) {
   376  	tt := encryptTests[0]
   377  	n := len(tt.key) + 28
   378  	c := &aesCipher{make([]uint32, n), make([]uint32, n)}
   379  	b.ResetTimer()
   380  	for i := 0; i < b.N; i++ {
   381  		expandKey(tt.key, c.enc, c.dec)
   382  	}
   383  }
   384  

View as plain text