1// Copyright 2020 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15//////////////////////////////////////////////////////////////////////////////// 16 17package subtle_test 18 19import ( 20 "bytes" 21 "encoding/hex" 22 "encoding/json" 23 "os" 24 "path/filepath" 25 "testing" 26 27 "github.com/google/tink/go/daead/subtle" 28 "github.com/google/tink/go/subtle/random" 29) 30 31type testData struct { 32 Algorithm string 33 GeneratorVersion string 34 NumberOfTests uint32 35 TestGroups []*testGroup 36} 37 38type testGroup struct { 39 KeySize uint32 40 Type string 41 Tests []*testCase 42} 43 44type testCase struct { 45 TcID uint32 46 Key string 47 Aad string 48 Msg string 49 Ct string 50 Result string 51} 52 53func TestAESSIV_EncryptDecrypt(t *testing.T) { 54 keyStr := 55 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + 56 "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" 57 key, _ := hex.DecodeString(keyStr) 58 msg := []byte("Some data to encrypt.") 59 aad := []byte("Additional data") 60 61 a, err := subtle.NewAESSIV(key) 62 if err != nil { 63 t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) 64 } 65 66 ct, err := a.EncryptDeterministically(msg, aad) 67 if err != nil { 68 t.Errorf("Unexpected encryption error: %v", err) 69 } 70 71 if pt, err := a.DecryptDeterministically(ct, aad); err != nil { 72 t.Errorf("Unexpected decryption error: %v", err) 73 } else if !bytes.Equal(pt, msg) { 74 t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) 75 } 76} 77 78func TestAESSIV_EmptyPlaintext(t *testing.T) { 79 keyStr := 80 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + 81 "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" 82 key, _ := hex.DecodeString(keyStr) 83 aad := []byte("Additional data") 84 85 a, err := subtle.NewAESSIV(key) 86 if err != nil { 87 t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) 88 } 89 90 ct, err := a.EncryptDeterministically(nil, aad) 91 if err != nil { 92 t.Errorf("Unexpected encryption error: %v", err) 93 } 94 if pt, err := a.DecryptDeterministically(ct, aad); err != nil { 95 t.Errorf("Unexpected decryption error: %v", err) 96 } else if !bytes.Equal(pt, []byte{}) { 97 t.Errorf("Mismatched plaintexts: got %v, want []", pt) 98 } 99 100 ct, err = a.EncryptDeterministically([]byte{}, aad) 101 if err != nil { 102 t.Errorf("Unexpected encryption error: %v", err) 103 } 104 if pt, err := a.DecryptDeterministically(ct, aad); err != nil { 105 t.Errorf("Unexpected decryption error: %v", err) 106 } else if !bytes.Equal(pt, []byte{}) { 107 t.Errorf("Mismatched plaintexts: got %v, want []", pt) 108 } 109} 110 111func TestAESSIV_EmptyAdditionalData(t *testing.T) { 112 keyStr := 113 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + 114 "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" 115 key, _ := hex.DecodeString(keyStr) 116 117 a, err := subtle.NewAESSIV(key) 118 if err != nil { 119 t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) 120 } 121 122 ct, err := a.EncryptDeterministically(nil, nil) 123 if err != nil { 124 t.Errorf("Unexpected encryption error: %v", err) 125 } 126 127 if pt, err := a.DecryptDeterministically(ct, nil); err != nil { 128 t.Errorf("Unexpected decryption error: %v", err) 129 } else if !bytes.Equal(pt, []byte{}) { 130 t.Errorf("Mismatched plaintexts: got %v, want []", pt) 131 } 132 133 if pt, err := a.DecryptDeterministically(ct, []byte{}); err != nil { 134 t.Errorf("Unexpected decryption error: %v", err) 135 } else if !bytes.Equal(pt, []byte{}) { 136 t.Errorf("Mismatched plaintexts: got %v, want []", pt) 137 } 138} 139 140func TestAESSIV_KeySizes(t *testing.T) { 141 keyStr := 142 "198371900187498172316311acf81d238ff7619873a61983d619c87b63a1987f" + 143 "987131819803719b847126381cd763871638aa71638176328761287361231321" + 144 "812731321de508761437195ff231765aa4913219873ac6918639816312130011" + 145 "abc900bba11400187984719827431246bbab1231eb4145215ff7141436616beb" + 146 "9817298148712fed3aab61000ff123313e" 147 key, _ := hex.DecodeString(keyStr) 148 149 for i := 0; i < len(key); i++ { 150 _, err := subtle.NewAESSIV(key[:i]) 151 if i == subtle.AESSIVKeySize && err != nil { 152 t.Errorf("Rejected valid key size: %v, %v", i, err) 153 } 154 if i != subtle.AESSIVKeySize && err == nil { 155 t.Errorf("Allowed invalid key size: %v", i) 156 } 157 } 158} 159 160func TestAESSIV_MessageSizes(t *testing.T) { 161 keyStr := 162 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + 163 "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" 164 key, _ := hex.DecodeString(keyStr) 165 aad := []byte("Additional data") 166 167 a, err := subtle.NewAESSIV(key) 168 if err != nil { 169 t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) 170 } 171 172 for i := uint32(0); i < 1024; i++ { 173 msg := random.GetRandomBytes(i) 174 ct, err := a.EncryptDeterministically(msg, aad) 175 if err != nil { 176 t.Errorf("Unexpected encryption error: %v", err) 177 } 178 if pt, err := a.DecryptDeterministically(ct, aad); err != nil { 179 t.Errorf("Unexpected decryption error: %v", err) 180 } else if !bytes.Equal(pt, msg) { 181 t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) 182 } 183 } 184 185 for i := uint32(1024); i < 100000; i += 5000 { 186 msg := random.GetRandomBytes(i) 187 ct, err := a.EncryptDeterministically(msg, aad) 188 if err != nil { 189 t.Errorf("Unexpected encryption error: %v", err) 190 } 191 if pt, err := a.DecryptDeterministically(ct, aad); err != nil { 192 t.Errorf("Unexpected decryption error: %v", err) 193 } else if !bytes.Equal(pt, msg) { 194 t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) 195 } 196 } 197} 198 199func TestAESSIV_AdditionalDataSizes(t *testing.T) { 200 keyStr := 201 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + 202 "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" 203 key, _ := hex.DecodeString(keyStr) 204 msg := []byte("Some data to encrypt.") 205 206 a, err := subtle.NewAESSIV(key) 207 if err != nil { 208 t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) 209 } 210 211 for i := uint32(0); i < 1024; i++ { 212 aad := random.GetRandomBytes(i) 213 ct, err := a.EncryptDeterministically(msg, aad) 214 if err != nil { 215 t.Errorf("Unexpected encryption error: %v", err) 216 } 217 if pt, err := a.DecryptDeterministically(ct, aad); err != nil { 218 t.Errorf("Unexpected decryption error: %v", err) 219 } else if !bytes.Equal(pt, msg) { 220 t.Errorf("Mismatched plaintexts: got %v, want %v", pt, msg) 221 } 222 } 223} 224 225func TestAESSIV_CiphertextModifications(t *testing.T) { 226 keyStr := 227 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + 228 "00112233445566778899aabbccddeefff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff" 229 key, _ := hex.DecodeString(keyStr) 230 aad := []byte("Additional data") 231 232 a, err := subtle.NewAESSIV(key) 233 if err != nil { 234 t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) 235 } 236 237 for i := uint32(0); i < 50; i++ { 238 msg := random.GetRandomBytes(i) 239 ct, err := a.EncryptDeterministically(msg, aad) 240 if err != nil { 241 t.Errorf("Unexpected encryption error: %v", err) 242 } 243 for j := 0; j < len(ct); j++ { 244 for b := uint32(0); b < 8; b++ { 245 ct[j] ^= 1 << b 246 if _, err := a.DecryptDeterministically(ct, aad); err == nil { 247 t.Errorf("Modified ciphertext decrypted: byte %d, bit %d", j, b) 248 } 249 ct[j] ^= 1 << b 250 } 251 } 252 } 253} 254 255func TestAESSIV_WycheproofVectors(t *testing.T) { 256 srcDir, ok := os.LookupEnv("TEST_SRCDIR") 257 if !ok { 258 t.Skip("TEST_SRCDIR not set") 259 } 260 f, err := os.Open(filepath.Join(srcDir, "wycheproof/testvectors/aes_siv_cmac_test.json")) 261 if err != nil { 262 t.Fatalf("Cannot open file: %s", err) 263 } 264 parser := json.NewDecoder(f) 265 data := new(testData) 266 if err := parser.Decode(data); err != nil { 267 t.Fatalf("Cannot decode test data: %s", err) 268 } 269 270 for _, g := range data.TestGroups { 271 if g.KeySize/8 != subtle.AESSIVKeySize { 272 continue 273 } 274 275 for _, tc := range g.Tests { 276 key, err := hex.DecodeString(tc.Key) 277 if err != nil { 278 t.Errorf("#%d, cannot decode key: %s", tc.TcID, err) 279 } 280 aad, err := hex.DecodeString(tc.Aad) 281 if err != nil { 282 t.Errorf("#%d, cannot decode aad: %s", tc.TcID, err) 283 } 284 msg, err := hex.DecodeString(tc.Msg) 285 if err != nil { 286 t.Errorf("#%d, cannot decode msg: %s", tc.TcID, err) 287 } 288 ct, err := hex.DecodeString(tc.Ct) 289 if err != nil { 290 t.Errorf("#%d, cannot decode ct: %s", tc.TcID, err) 291 } 292 293 a, err := subtle.NewAESSIV(key) 294 if err != nil { 295 t.Errorf("NewAESSIV(key) = _, %v, want _, nil", err) 296 continue 297 } 298 299 // EncryptDeterministically should always succeed since msg and aad are valid inputs. 300 gotCt, err := a.EncryptDeterministically(msg, aad) 301 if err != nil { 302 t.Errorf("#%d, unexpected encryption error: %v", tc.TcID, err) 303 } else { 304 if tc.Result == "valid" && !bytes.Equal(gotCt, ct) { 305 t.Errorf("#%d, incorrect encryption: got %v, want %v", tc.TcID, gotCt, ct) 306 } 307 if tc.Result == "invalid" && bytes.Equal(gotCt, ct) { 308 t.Errorf("#%d, invalid encryption: got %v, want %v", tc.TcID, gotCt, ct) 309 } 310 } 311 312 pt, err := a.DecryptDeterministically(ct, aad) 313 if tc.Result == "valid" { 314 if err != nil { 315 t.Errorf("#%d, unexpected decryption error: %v", tc.TcID, err) 316 } else if !bytes.Equal(pt, msg) { 317 t.Errorf("#%d, incorrect decryption: got %v, want %v", tc.TcID, pt, msg) 318 } 319 } else { 320 if err == nil { 321 t.Errorf("#%d, decryption error expected: got nil", tc.TcID) 322 } 323 } 324 } 325 } 326} 327