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 }