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  	"crypto/internal/cryptotest"
     9  	"fmt"
    10  	"testing"
    11  )
    12  
    13  // See const.go for overview of math here.
    14  
    15  // Test that powx is initialized correctly.
    16  // (Can adapt this code to generate it too.)
    17  func TestPowx(t *testing.T) {
    18  	p := 1
    19  	for i := 0; i < len(powx); i++ {
    20  		if powx[i] != byte(p) {
    21  			t.Errorf("powx[%d] = %#x, want %#x", i, powx[i], p)
    22  		}
    23  		p <<= 1
    24  		if p&0x100 != 0 {
    25  			p ^= poly
    26  		}
    27  	}
    28  }
    29  
    30  // Multiply b and c as GF(2) polynomials modulo poly
    31  func mul(b, c uint32) uint32 {
    32  	i := b
    33  	j := c
    34  	s := uint32(0)
    35  	for k := uint32(1); k < 0x100 && j != 0; k <<= 1 {
    36  		// Invariant: k == 1<<n, i == b * xⁿ
    37  
    38  		if j&k != 0 {
    39  			// s += i in GF(2); xor in binary
    40  			s ^= i
    41  			j ^= k // turn off bit to end loop early
    42  		}
    43  
    44  		// i *= x in GF(2) modulo the polynomial
    45  		i <<= 1
    46  		if i&0x100 != 0 {
    47  			i ^= poly
    48  		}
    49  	}
    50  	return s
    51  }
    52  
    53  // Test all mul inputs against bit-by-bit n² algorithm.
    54  func TestMul(t *testing.T) {
    55  	for i := uint32(0); i < 256; i++ {
    56  		for j := uint32(0); j < 256; j++ {
    57  			// Multiply i, j bit by bit.
    58  			s := uint8(0)
    59  			for k := uint(0); k < 8; k++ {
    60  				for l := uint(0); l < 8; l++ {
    61  					if i&(1<<k) != 0 && j&(1<<l) != 0 {
    62  						s ^= powx[k+l]
    63  					}
    64  				}
    65  			}
    66  			if x := mul(i, j); x != uint32(s) {
    67  				t.Fatalf("mul(%#x, %#x) = %#x, want %#x", i, j, x, s)
    68  			}
    69  		}
    70  	}
    71  }
    72  
    73  // Check that S-boxes are inverses of each other.
    74  // They have more structure that we could test,
    75  // but if this sanity check passes, we'll assume
    76  // the cut and paste from the FIPS PDF worked.
    77  func TestSboxes(t *testing.T) {
    78  	for i := 0; i < 256; i++ {
    79  		if j := sbox0[sbox1[i]]; j != byte(i) {
    80  			t.Errorf("sbox0[sbox1[%#x]] = %#x", i, j)
    81  		}
    82  		if j := sbox1[sbox0[i]]; j != byte(i) {
    83  			t.Errorf("sbox1[sbox0[%#x]] = %#x", i, j)
    84  		}
    85  	}
    86  }
    87  
    88  // Test that encryption tables are correct.
    89  // (Can adapt this code to generate them too.)
    90  func TestTe(t *testing.T) {
    91  	for i := 0; i < 256; i++ {
    92  		s := uint32(sbox0[i])
    93  		s2 := mul(s, 2)
    94  		s3 := mul(s, 3)
    95  		w := s2<<24 | s<<16 | s<<8 | s3
    96  		te := [][256]uint32{te0, te1, te2, te3}
    97  		for j := 0; j < 4; j++ {
    98  			if x := te[j][i]; x != w {
    99  				t.Fatalf("te[%d][%d] = %#x, want %#x", j, i, x, w)
   100  			}
   101  			w = w<<24 | w>>8
   102  		}
   103  	}
   104  }
   105  
   106  // Test that decryption tables are correct.
   107  // (Can adapt this code to generate them too.)
   108  func TestTd(t *testing.T) {
   109  	for i := 0; i < 256; i++ {
   110  		s := uint32(sbox1[i])
   111  		s9 := mul(s, 0x9)
   112  		sb := mul(s, 0xb)
   113  		sd := mul(s, 0xd)
   114  		se := mul(s, 0xe)
   115  		w := se<<24 | s9<<16 | sd<<8 | sb
   116  		td := [][256]uint32{td0, td1, td2, td3}
   117  		for j := 0; j < 4; j++ {
   118  			if x := td[j][i]; x != w {
   119  				t.Fatalf("td[%d][%d] = %#x, want %#x", j, i, x, w)
   120  			}
   121  			w = w<<24 | w>>8
   122  		}
   123  	}
   124  }
   125  
   126  // Test vectors are from FIPS 197:
   127  //	https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
   128  
   129  // Appendix A of FIPS 197: Key expansion examples
   130  type KeyTest struct {
   131  	key []byte
   132  	enc []uint32
   133  	dec []uint32 // decryption expansion; not in FIPS 197, computed from C implementation.
   134  }
   135  
   136  var keyTests = []KeyTest{
   137  	{
   138  		// A.1.  Expansion of a 128-bit Cipher Key
   139  		[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
   140  		[]uint32{
   141  			0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c,
   142  			0xa0fafe17, 0x88542cb1, 0x23a33939, 0x2a6c7605,
   143  			0xf2c295f2, 0x7a96b943, 0x5935807a, 0x7359f67f,
   144  			0x3d80477d, 0x4716fe3e, 0x1e237e44, 0x6d7a883b,
   145  			0xef44a541, 0xa8525b7f, 0xb671253b, 0xdb0bad00,
   146  			0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc,
   147  			0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd,
   148  			0x4e54f70e, 0x5f5fc9f3, 0x84a64fb2, 0x4ea6dc4f,
   149  			0xead27321, 0xb58dbad2, 0x312bf560, 0x7f8d292f,
   150  			0xac7766f3, 0x19fadc21, 0x28d12941, 0x575c006e,
   151  			0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6,
   152  		},
   153  		[]uint32{
   154  			0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6,
   155  			0xc7b5a63, 0x1319eafe, 0xb0398890, 0x664cfbb4,
   156  			0xdf7d925a, 0x1f62b09d, 0xa320626e, 0xd6757324,
   157  			0x12c07647, 0xc01f22c7, 0xbc42d2f3, 0x7555114a,
   158  			0x6efcd876, 0xd2df5480, 0x7c5df034, 0xc917c3b9,
   159  			0x6ea30afc, 0xbc238cf6, 0xae82a4b4, 0xb54a338d,
   160  			0x90884413, 0xd280860a, 0x12a12842, 0x1bc89739,
   161  			0x7c1f13f7, 0x4208c219, 0xc021ae48, 0x969bf7b,
   162  			0xcc7505eb, 0x3e17d1ee, 0x82296c51, 0xc9481133,
   163  			0x2b3708a7, 0xf262d405, 0xbc3ebdbf, 0x4b617d62,
   164  			0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x9cf4f3c,
   165  		},
   166  	},
   167  	{
   168  		// A.2.  Expansion of a 192-bit Cipher Key
   169  		[]byte{
   170  			0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
   171  			0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
   172  		},
   173  		[]uint32{
   174  			0x8e73b0f7, 0xda0e6452, 0xc810f32b, 0x809079e5,
   175  			0x62f8ead2, 0x522c6b7b, 0xfe0c91f7, 0x2402f5a5,
   176  			0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2,
   177  			0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd,
   178  			0xe75fad44, 0xbb095386, 0x485af057, 0x21efb14f,
   179  			0xa448f6d9, 0x4d6dce24, 0xaa326360, 0x113b30e6,
   180  			0xa25e7ed5, 0x83b1cf9a, 0x27f93943, 0x6a94f767,
   181  			0xc0a69407, 0xd19da4e1, 0xec1786eb, 0x6fa64971,
   182  			0x485f7032, 0x22cb8755, 0xe26d1352, 0x33f0b7b3,
   183  			0x40beeb28, 0x2f18a259, 0x6747d26b, 0x458c553e,
   184  			0xa7e1466c, 0x9411f1df, 0x821f750a, 0xad07d753,
   185  			0xca400538, 0x8fcc5006, 0x282d166a, 0xbc3ce7b5,
   186  			0xe98ba06f, 0x448c773c, 0x8ecc7204, 0x01002202,
   187  		},
   188  		nil,
   189  	},
   190  	{
   191  		// A.3.  Expansion of a 256-bit Cipher Key
   192  		[]byte{
   193  			0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
   194  			0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
   195  		},
   196  		[]uint32{
   197  			0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781,
   198  			0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4,
   199  			0x9ba35411, 0x8e6925af, 0xa51a8b5f, 0x2067fcde,
   200  			0xa8b09c1a, 0x93d194cd, 0xbe49846e, 0xb75d5b9a,
   201  			0xd59aecb8, 0x5bf3c917, 0xfee94248, 0xde8ebe96,
   202  			0xb5a9328a, 0x2678a647, 0x98312229, 0x2f6c79b3,
   203  			0x812c81ad, 0xdadf48ba, 0x24360af2, 0xfab8b464,
   204  			0x98c5bfc9, 0xbebd198e, 0x268c3ba7, 0x09e04214,
   205  			0x68007bac, 0xb2df3316, 0x96e939e4, 0x6c518d80,
   206  			0xc814e204, 0x76a9fb8a, 0x5025c02d, 0x59c58239,
   207  			0xde136967, 0x6ccc5a71, 0xfa256395, 0x9674ee15,
   208  			0x5886ca5d, 0x2e2f31d7, 0x7e0af1fa, 0x27cf73c3,
   209  			0x749c47ab, 0x18501dda, 0xe2757e4f, 0x7401905a,
   210  			0xcafaaae3, 0xe4d59b34, 0x9adf6ace, 0xbd10190d,
   211  			0xfe4890d1, 0xe6188d0b, 0x046df344, 0x706c631e,
   212  		},
   213  		nil,
   214  	},
   215  }
   216  
   217  // Test key expansion against FIPS 197 examples.
   218  func TestExpandKey(t *testing.T) {
   219  L:
   220  	for i, tt := range keyTests {
   221  		enc := make([]uint32, len(tt.enc))
   222  		var dec []uint32
   223  		if tt.dec != nil {
   224  			dec = make([]uint32, len(tt.dec))
   225  		}
   226  		// This test could only test Go version of expandKey because asm
   227  		// version might use different memory layout for expanded keys
   228  		// This is OK because we don't expose expanded keys to the outside
   229  		expandKeyGo(tt.key, enc, dec)
   230  		for j, v := range enc {
   231  			if v != tt.enc[j] {
   232  				t.Errorf("key %d: enc[%d] = %#x, want %#x", i, j, v, tt.enc[j])
   233  				continue L
   234  			}
   235  		}
   236  		for j, v := range dec {
   237  			if v != tt.dec[j] {
   238  				t.Errorf("key %d: dec[%d] = %#x, want %#x", i, j, v, tt.dec[j])
   239  				continue L
   240  			}
   241  		}
   242  	}
   243  }
   244  
   245  // Appendix B, C of FIPS 197: Cipher examples, Example vectors.
   246  type CryptTest struct {
   247  	key []byte
   248  	in  []byte
   249  	out []byte
   250  }
   251  
   252  var 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.
   284  func 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.
   303  func 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 AES against the general cipher.Block interface tester
   322  func TestAESBlock(t *testing.T) {
   323  	for _, keylen := range []int{128, 192, 256} {
   324  		t.Run(fmt.Sprintf("AES-%d", keylen), func(t *testing.T) {
   325  			cryptotest.TestBlock(t, keylen/8, NewCipher)
   326  		})
   327  	}
   328  }
   329  
   330  func BenchmarkEncrypt(b *testing.B) {
   331  	b.Run("AES-128", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[1]) })
   332  	b.Run("AES-192", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[2]) })
   333  	b.Run("AES-256", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[3]) })
   334  }
   335  
   336  func benchmarkEncrypt(b *testing.B, tt CryptTest) {
   337  	c, err := NewCipher(tt.key)
   338  	if err != nil {
   339  		b.Fatal("NewCipher:", err)
   340  	}
   341  	out := make([]byte, len(tt.in))
   342  	b.SetBytes(int64(len(out)))
   343  	b.ResetTimer()
   344  	for i := 0; i < b.N; i++ {
   345  		c.Encrypt(out, tt.in)
   346  	}
   347  }
   348  
   349  func BenchmarkDecrypt(b *testing.B) {
   350  	b.Run("AES-128", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[1]) })
   351  	b.Run("AES-192", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[2]) })
   352  	b.Run("AES-256", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[3]) })
   353  }
   354  
   355  func benchmarkDecrypt(b *testing.B, tt CryptTest) {
   356  	c, err := NewCipher(tt.key)
   357  	if err != nil {
   358  		b.Fatal("NewCipher:", err)
   359  	}
   360  	out := make([]byte, len(tt.out))
   361  	b.SetBytes(int64(len(out)))
   362  	b.ResetTimer()
   363  	for i := 0; i < b.N; i++ {
   364  		c.Decrypt(out, tt.out)
   365  	}
   366  }
   367  
   368  func BenchmarkExpand(b *testing.B) {
   369  	b.Run("AES-128", func(b *testing.B) { benchmarkExpand(b, encryptTests[1]) })
   370  	b.Run("AES-192", func(b *testing.B) { benchmarkExpand(b, encryptTests[2]) })
   371  	b.Run("AES-256", func(b *testing.B) { benchmarkExpand(b, encryptTests[3]) })
   372  }
   373  
   374  func benchmarkExpand(b *testing.B, tt CryptTest) {
   375  	c := &aesCipher{l: uint8(len(tt.key) + 28)}
   376  	b.ResetTimer()
   377  	for i := 0; i < b.N; i++ {
   378  		expandKey(tt.key, c.enc[:c.l], c.dec[:c.l])
   379  	}
   380  }
   381  
   382  func BenchmarkCreateCipher(b *testing.B) {
   383  	b.Run("AES-128", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[1]) })
   384  	b.Run("AES-192", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[2]) })
   385  	b.Run("AES-256", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[3]) })
   386  }
   387  
   388  func benchmarkCreateCipher(b *testing.B, tt CryptTest) {
   389  	b.ReportAllocs()
   390  	for i := 0; i < b.N; i++ {
   391  		if _, err := NewCipher(tt.key); err != nil {
   392  			b.Fatal(err)
   393  		}
   394  	}
   395  }
   396  

View as plain text