github.com/fawick/restic@v0.1.1-0.20171126184616-c02923fbfc79/internal/crypto/crypto_int_test.go (about)

     1  package crypto
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"testing"
     7  )
     8  
     9  // test vectors from http://cr.yp.to/mac/poly1305-20050329.pdf
    10  var poly1305Tests = []struct {
    11  	msg   []byte
    12  	r     []byte
    13  	k     []byte
    14  	nonce []byte
    15  	mac   []byte
    16  }{
    17  	{
    18  		[]byte("\xf3\xf6"),
    19  		[]byte("\x85\x1f\xc4\x0c\x34\x67\xac\x0b\xe0\x5c\xc2\x04\x04\xf3\xf7\x00"),
    20  		[]byte("\xec\x07\x4c\x83\x55\x80\x74\x17\x01\x42\x5b\x62\x32\x35\xad\xd6"),
    21  		[]byte("\xfb\x44\x73\x50\xc4\xe8\x68\xc5\x2a\xc3\x27\x5c\xf9\xd4\x32\x7e"),
    22  		[]byte("\xf4\xc6\x33\xc3\x04\x4f\xc1\x45\xf8\x4f\x33\x5c\xb8\x19\x53\xde"),
    23  	},
    24  	{
    25  		[]byte(""),
    26  		[]byte("\xa0\xf3\x08\x00\x00\xf4\x64\x00\xd0\xc7\xe9\x07\x6c\x83\x44\x03"),
    27  		[]byte("\x75\xde\xaa\x25\xc0\x9f\x20\x8e\x1d\xc4\xce\x6b\x5c\xad\x3f\xbf"),
    28  		[]byte("\x61\xee\x09\x21\x8d\x29\xb0\xaa\xed\x7e\x15\x4a\x2c\x55\x09\xcc"),
    29  		[]byte("\xdd\x3f\xab\x22\x51\xf1\x1a\xc7\x59\xf0\x88\x71\x29\xcc\x2e\xe7"),
    30  	},
    31  	{
    32  		[]byte("\x66\x3c\xea\x19\x0f\xfb\x83\xd8\x95\x93\xf3\xf4\x76\xb6\xbc\x24\xd7\xe6\x79\x10\x7e\xa2\x6a\xdb\x8c\xaf\x66\x52\xd0\x65\x61\x36"),
    33  		[]byte("\x48\x44\x3d\x0b\xb0\xd2\x11\x09\xc8\x9a\x10\x0b\x5c\xe2\xc2\x08"),
    34  		[]byte("\x6a\xcb\x5f\x61\xa7\x17\x6d\xd3\x20\xc5\xc1\xeb\x2e\xdc\xdc\x74"),
    35  		[]byte("\xae\x21\x2a\x55\x39\x97\x29\x59\x5d\xea\x45\x8b\xc6\x21\xff\x0e"),
    36  		[]byte("\x0e\xe1\xc1\x6b\xb7\x3f\x0f\x4f\xd1\x98\x81\x75\x3c\x01\xcd\xbe"),
    37  	}, {
    38  		[]byte("\xab\x08\x12\x72\x4a\x7f\x1e\x34\x27\x42\xcb\xed\x37\x4d\x94\xd1\x36\xc6\xb8\x79\x5d\x45\xb3\x81\x98\x30\xf2\xc0\x44\x91\xfa\xf0\x99\x0c\x62\xe4\x8b\x80\x18\xb2\xc3\xe4\xa0\xfa\x31\x34\xcb\x67\xfa\x83\xe1\x58\xc9\x94\xd9\x61\xc4\xcb\x21\x09\x5c\x1b\xf9"),
    39  		[]byte("\x12\x97\x6a\x08\xc4\x42\x6d\x0c\xe8\xa8\x24\x07\xc4\xf4\x82\x07"),
    40  		[]byte("\xe1\xa5\x66\x8a\x4d\x5b\x66\xa5\xf6\x8c\xc5\x42\x4e\xd5\x98\x2d"),
    41  		[]byte("\x9a\xe8\x31\xe7\x43\x97\x8d\x3a\x23\x52\x7c\x71\x28\x14\x9e\x3a"),
    42  		[]byte("\x51\x54\xad\x0d\x2c\xb2\x6e\x01\x27\x4f\xc5\x11\x48\x49\x1f\x1b"),
    43  	},
    44  }
    45  
    46  func TestPoly1305(t *testing.T) {
    47  	for _, test := range poly1305Tests {
    48  		key := &MACKey{}
    49  		copy(key.K[:], test.k)
    50  		copy(key.R[:], test.r)
    51  		mac := poly1305MAC(test.msg, test.nonce, key)
    52  
    53  		if !bytes.Equal(mac, test.mac) {
    54  			t.Fatalf("wrong mac calculated, want: %02x, got: %02x", test.mac, mac)
    55  		}
    56  
    57  		if !poly1305Verify(test.msg, test.nonce, key, test.mac) {
    58  			t.Fatalf("mac does not verify: mac: %02x", test.mac)
    59  		}
    60  	}
    61  }
    62  
    63  var testValues = []struct {
    64  	ekey       EncryptionKey
    65  	skey       MACKey
    66  	ciphertext []byte
    67  	plaintext  []byte
    68  }{
    69  	{
    70  		ekey: decodeArray32("303e8687b1d7db18421bdc6bb8588ccadac4d59ee87b8ff70c44e635790cafef"),
    71  		skey: MACKey{
    72  			K: decodeArray16("ef4d8824cb80b2bcc5fbff8a9b12a42c"),
    73  			R: decodeArray16("cc8d4b948ee0ebfe1d415de921d10353"),
    74  		},
    75  		ciphertext: decodeHex("69fb41c62d12def4593bd71757138606338f621aeaeb39da0fe4f99233f8037a54ea63338a813bcf3f75d8c3cc75dddf8750"),
    76  		plaintext:  []byte("Dies ist ein Test!"),
    77  	},
    78  }
    79  
    80  func decodeArray16(s string) (dst [16]byte) {
    81  	data := decodeHex(s)
    82  	if len(data) != 16 {
    83  		panic("data has wrong length")
    84  	}
    85  	copy(dst[:], data)
    86  	return
    87  }
    88  
    89  func decodeArray32(s string) (dst [32]byte) {
    90  	data := decodeHex(s)
    91  	if len(data) != 32 {
    92  		panic("data has wrong length")
    93  	}
    94  	copy(dst[:], data)
    95  	return
    96  }
    97  
    98  // decodeHex decodes the string s and panics on error.
    99  func decodeHex(s string) []byte {
   100  	d, err := hex.DecodeString(s)
   101  	if err != nil {
   102  		panic(err)
   103  	}
   104  	return d
   105  }
   106  
   107  func TestCrypto(t *testing.T) {
   108  	msg := make([]byte, 0, 8*1024*1024) // use 8MiB for now
   109  	for _, tv := range testValues {
   110  		// test encryption
   111  		k := &Key{
   112  			EncryptionKey: tv.ekey,
   113  			MACKey:        tv.skey,
   114  		}
   115  
   116  		nonce := NewRandomNonce()
   117  		ciphertext := k.Seal(msg[0:], nonce, tv.plaintext, nil)
   118  
   119  		// decrypt message
   120  		buf := make([]byte, 0, len(tv.plaintext))
   121  		buf, err := k.Open(buf, nonce, ciphertext, nil)
   122  		if err != nil {
   123  			t.Fatal(err)
   124  		}
   125  
   126  		if !bytes.Equal(buf, tv.plaintext) {
   127  			t.Fatalf("wrong plaintext returned")
   128  		}
   129  
   130  		// change mac, this must fail
   131  		ciphertext[len(ciphertext)-8] ^= 0x23
   132  
   133  		if _, err = k.Open(buf[:0], nonce, ciphertext, nil); err != ErrUnauthenticated {
   134  			t.Fatal("wrong MAC value not detected")
   135  		}
   136  		// reset mac
   137  		ciphertext[len(ciphertext)-8] ^= 0x23
   138  
   139  		// tamper with nonce, this must fail
   140  		nonce[2] ^= 0x88
   141  		if _, err = k.Open(buf[:0], nonce, ciphertext, nil); err != ErrUnauthenticated {
   142  			t.Fatal("tampered nonce not detected")
   143  		}
   144  		// reset nonce
   145  		nonce[2] ^= 0x88
   146  
   147  		// tamper with message, this must fail
   148  		ciphertext[16+5] ^= 0x85
   149  		if _, err = k.Open(buf[:0], nonce, ciphertext, nil); err != ErrUnauthenticated {
   150  			t.Fatal("tampered message not detected")
   151  		}
   152  
   153  		// test decryption
   154  		p := make([]byte, len(tv.ciphertext))
   155  		nonce, ciphertext = tv.ciphertext[:16], tv.ciphertext[16:]
   156  		p, err = k.Open(p[:0], nonce, ciphertext, nil)
   157  		if err != nil {
   158  			t.Fatal(err)
   159  		}
   160  
   161  		if !bytes.Equal(p, tv.plaintext) {
   162  			t.Fatalf("wrong plaintext: expected %q but got %q\n", tv.plaintext, p)
   163  		}
   164  	}
   165  }
   166  
   167  func TestNonceVadlid(t *testing.T) {
   168  	nonce := make([]byte, ivSize)
   169  
   170  	if validNonce(nonce) {
   171  		t.Error("null nonce detected as valid")
   172  	}
   173  
   174  	for i := 0; i < 100; i++ {
   175  		nonce = NewRandomNonce()
   176  		if !validNonce(nonce) {
   177  			t.Errorf("random nonce not detected as valid: %02x", nonce)
   178  		}
   179  	}
   180  }
   181  
   182  func BenchmarkNonceValid(b *testing.B) {
   183  	nonce := NewRandomNonce()
   184  
   185  	b.ResetTimer()
   186  
   187  	for i := 0; i < b.N; i++ {
   188  		if !validNonce(nonce) {
   189  			b.Fatal("nonce is invalid")
   190  		}
   191  	}
   192  }