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/boring"
     9  	"crypto/internal/cryptotest"
    10  	"fmt"
    11  	"testing"
    12  )
    13  
    14  // Test vectors are from FIPS 197:
    15  //	https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
    16  
    17  // Appendix B, C of FIPS 197: Cipher examples, Example vectors.
    18  type CryptTest struct {
    19  	key []byte
    20  	in  []byte
    21  	out []byte
    22  }
    23  
    24  var encryptTests = []CryptTest{
    25  	{
    26  		// Appendix B.
    27  		[]byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c},
    28  		[]byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34},
    29  		[]byte{0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32},
    30  	},
    31  	{
    32  		// Appendix C.1.  AES-128
    33  		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
    34  		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
    35  		[]byte{0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a},
    36  	},
    37  	{
    38  		// Appendix C.2.  AES-192
    39  		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    40  			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    41  		},
    42  		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
    43  		[]byte{0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91},
    44  	},
    45  	{
    46  		// Appendix C.3.  AES-256
    47  		[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    48  			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    49  		},
    50  		[]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
    51  		[]byte{0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89},
    52  	},
    53  }
    54  
    55  // Test Cipher Encrypt method against FIPS 197 examples.
    56  func TestCipherEncrypt(t *testing.T) {
    57  	cryptotest.TestAllImplementations(t, "aes", testCipherEncrypt)
    58  }
    59  
    60  func testCipherEncrypt(t *testing.T) {
    61  	for i, tt := range encryptTests {
    62  		c, err := NewCipher(tt.key)
    63  		if err != nil {
    64  			t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
    65  			continue
    66  		}
    67  		out := make([]byte, len(tt.in))
    68  		c.Encrypt(out, tt.in)
    69  		for j, v := range out {
    70  			if v != tt.out[j] {
    71  				t.Errorf("Cipher.Encrypt %d: out[%d] = %#x, want %#x", i, j, v, tt.out[j])
    72  				break
    73  			}
    74  		}
    75  	}
    76  }
    77  
    78  // Test Cipher Decrypt against FIPS 197 examples.
    79  func TestCipherDecrypt(t *testing.T) {
    80  	cryptotest.TestAllImplementations(t, "aes", testCipherDecrypt)
    81  }
    82  
    83  func testCipherDecrypt(t *testing.T) {
    84  	for i, tt := range encryptTests {
    85  		c, err := NewCipher(tt.key)
    86  		if err != nil {
    87  			t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
    88  			continue
    89  		}
    90  		plain := make([]byte, len(tt.in))
    91  		c.Decrypt(plain, tt.out)
    92  		for j, v := range plain {
    93  			if v != tt.in[j] {
    94  				t.Errorf("decryptBlock %d: plain[%d] = %#x, want %#x", i, j, v, tt.in[j])
    95  				break
    96  			}
    97  		}
    98  	}
    99  }
   100  
   101  // Test AES against the general cipher.Block interface tester
   102  func TestAESBlock(t *testing.T) {
   103  	cryptotest.TestAllImplementations(t, "aes", testAESBlock)
   104  }
   105  
   106  func testAESBlock(t *testing.T) {
   107  	for _, keylen := range []int{128, 192, 256} {
   108  		t.Run(fmt.Sprintf("AES-%d", keylen), func(t *testing.T) {
   109  			cryptotest.TestBlock(t, keylen/8, NewCipher)
   110  		})
   111  	}
   112  }
   113  
   114  func TestExtraMethods(t *testing.T) {
   115  	if boring.Enabled {
   116  		t.Skip("Go+BoringCrypto still uses the interface upgrades in crypto/cipher")
   117  	}
   118  	cryptotest.TestAllImplementations(t, "aes", func(t *testing.T) {
   119  		b, _ := NewCipher(make([]byte, 16))
   120  		cryptotest.NoExtraMethods(t, &b)
   121  	})
   122  }
   123  
   124  func BenchmarkEncrypt(b *testing.B) {
   125  	b.Run("AES-128", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[1]) })
   126  	b.Run("AES-192", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[2]) })
   127  	b.Run("AES-256", func(b *testing.B) { benchmarkEncrypt(b, encryptTests[3]) })
   128  }
   129  
   130  func benchmarkEncrypt(b *testing.B, tt CryptTest) {
   131  	c, err := NewCipher(tt.key)
   132  	if err != nil {
   133  		b.Fatal("NewCipher:", err)
   134  	}
   135  	out := make([]byte, len(tt.in))
   136  	b.SetBytes(int64(len(out)))
   137  	b.ResetTimer()
   138  	for i := 0; i < b.N; i++ {
   139  		c.Encrypt(out, tt.in)
   140  	}
   141  }
   142  
   143  func BenchmarkDecrypt(b *testing.B) {
   144  	b.Run("AES-128", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[1]) })
   145  	b.Run("AES-192", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[2]) })
   146  	b.Run("AES-256", func(b *testing.B) { benchmarkDecrypt(b, encryptTests[3]) })
   147  }
   148  
   149  func benchmarkDecrypt(b *testing.B, tt CryptTest) {
   150  	c, err := NewCipher(tt.key)
   151  	if err != nil {
   152  		b.Fatal("NewCipher:", err)
   153  	}
   154  	out := make([]byte, len(tt.out))
   155  	b.SetBytes(int64(len(out)))
   156  	b.ResetTimer()
   157  	for i := 0; i < b.N; i++ {
   158  		c.Decrypt(out, tt.out)
   159  	}
   160  }
   161  
   162  func BenchmarkCreateCipher(b *testing.B) {
   163  	b.Run("AES-128", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[1]) })
   164  	b.Run("AES-192", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[2]) })
   165  	b.Run("AES-256", func(b *testing.B) { benchmarkCreateCipher(b, encryptTests[3]) })
   166  }
   167  
   168  func benchmarkCreateCipher(b *testing.B, tt CryptTest) {
   169  	b.ReportAllocs()
   170  	for i := 0; i < b.N; i++ {
   171  		if _, err := NewCipher(tt.key); err != nil {
   172  			b.Fatal(err)
   173  		}
   174  	}
   175  }
   176  

View as plain text