1package s3crypto
2
3import (
4	"bytes"
5	"encoding/hex"
6	"fmt"
7	"io"
8	"testing"
9)
10
11func TestAESCBCEncryptDecrypt(t *testing.T) {
12	var testCases = []struct {
13		key        string
14		iv         string
15		plaintext  string
16		ciphertext string
17		decodeHex  bool
18		padder     Padder
19	}{
20		// Test vectors from RFC 3602: https://tools.ietf.org/html/rfc3602
21		{
22			"06a9214036b8a15b512e03d534120006",
23			"3dafba429d9eb430b422da802c9fac41",
24			"Single block msg",
25			"e353779c1079aeb82708942dbe77181a",
26			false,
27			NoPadder,
28		},
29		{
30			"c286696d887c9aa0611bbb3e2025a45a",
31			"562e17996d093d28ddb3ba695a2e6f58",
32			"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
33			"d296cd94c2cccf8a3a863028b5e1dc0a7586602d253cfff91b8266bea6d61ab1",
34			true,
35			NoPadder,
36		},
37		{
38			"6c3ea0477630ce21a2ce334aa746c2cd",
39			"c782dc4c098c66cbd9cd27d825682c81",
40			"This is a 48-byte message (exactly 3 AES blocks)",
41			"d0a02b3836451753d493665d33f0e8862dea54cdb293abc7506939276772f8d5021c19216bad525c8579695d83ba2684",
42			false,
43			NoPadder,
44		},
45		{
46			"56e47a38c5598974bc46903dba290349",
47			"8ce82eefbea0da3c44699ed7db51b7d9",
48			"a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf",
49			"c30e32ffedc0774e6aff6af0869f71aa0f3af07a9a31a9c684db207eb0ef8e4e35907aa632c3ffdf868bb7b29d3d46ad83ce9f9a102ee99d49a53e87f4c3da55",
50			true,
51			NoPadder,
52		},
53		{
54			"11111111111111111111111111111111",
55			"22222222222222222222222222222222",
56			"",
57			"B012949BA07D1A6DCE9DEE67274D41AB",
58			true,
59			AESCBCPadder,
60		},
61		{
62			"11111111111111111111111111111111",
63			"22222222222222222222222222222222",
64			"41",
65			"8A11ABA68A566132FFE04DB336621D41",
66			true,
67			AESCBCPadder,
68		},
69		{
70			"11111111111111111111111111111111",
71			"22222222222222222222222222222222",
72			"4141",
73			"97D0896E41DFDB5CEA4A9EB70A938CFD",
74			true,
75			AESCBCPadder,
76		},
77		{
78			"11111111111111111111111111111111",
79			"22222222222222222222222222222222",
80			"414141",
81			"8464EAD45FA2D8790E8741E32C28083F",
82			true,
83			AESCBCPadder,
84		},
85		{
86			"11111111111111111111111111111111",
87			"22222222222222222222222222222222",
88			"41414141",
89			"1E656D6E2745BA9F154FAF136B2BC73D",
90			true,
91			AESCBCPadder,
92		},
93		{
94			"11111111111111111111111111111111",
95			"22222222222222222222222222222222",
96			"4141414141",
97			"0B6031C4B230DAC6BD6D3F195645B287",
98			true,
99			AESCBCPadder,
100		},
101		{
102			"11111111111111111111111111111111",
103			"22222222222222222222222222222222",
104			"414141414141",
105			"5D09FEB6462BB489489A7E18FD341D9D",
106			true,
107			AESCBCPadder,
108		},
109		{
110			"11111111111111111111111111111111",
111			"22222222222222222222222222222222",
112			"41414141414141",
113			"85745E398F2FD1050C2CE8F8614DA369",
114			true,
115			AESCBCPadder,
116		},
117		{
118			"11111111111111111111111111111111",
119			"22222222222222222222222222222222",
120			"4141414141414141",
121			"7BE52933970BA7B0FC6FB3FC37648205",
122			true,
123			AESCBCPadder,
124		},
125		{
126			"11111111111111111111111111111111",
127			"22222222222222222222222222222222",
128			"414141414141414141",
129			"ED3A1E134EF36CCFE60C8123B4272F89",
130			true,
131			AESCBCPadder,
132		},
133		{
134			"11111111111111111111111111111111",
135			"22222222222222222222222222222222",
136			"41414141414141414141",
137			"C3B7C9E177E1052FC736F65FC1E74209",
138			true,
139			AESCBCPadder,
140		},
141		{
142			"11111111111111111111111111111111",
143			"22222222222222222222222222222222",
144			"4141414141414141414141",
145			"C3A8B53F7F57F0B9D346FA99810A3C28",
146			true,
147			AESCBCPadder,
148		},
149		{
150			"11111111111111111111111111111111",
151			"22222222222222222222222222222222",
152			"414141414141414141414141",
153			"D16B1ECE5BF00AF919E139E99775FF06",
154			true,
155			AESCBCPadder,
156		},
157		{
158			"11111111111111111111111111111111",
159			"22222222222222222222222222222222",
160			"41414141414141414141414141",
161			"B258F4DF57FFCA1EFCF8D76140F05139",
162			true,
163			AESCBCPadder,
164		},
165		{
166			"11111111111111111111111111111111",
167			"22222222222222222222222222222222",
168			"4141414141414141414141414141",
169			"3CD2282DE24A2CF9E23326CC3DC9077A",
170			true,
171			AESCBCPadder,
172		},
173		{
174			"11111111111111111111111111111111",
175			"22222222222222222222222222222222",
176			"414141414141414141414141414141",
177			"3010232E7C752A3B4C9EE428B4C4FE88",
178			true,
179			AESCBCPadder,
180		},
181		{
182			"11111111111111111111111111111111",
183			"22222222222222222222222222222222",
184			"41414141414141414141414141414141",
185			"C3304FA46097CBBA59085416764A217A22BC4E6D03BFD2418DD412D1ED1B31AF",
186			true,
187			AESCBCPadder,
188		},
189		{
190			"11111111111111111111111111111111",
191			"22222222222222222222222222222222",
192			"4141414141414141414141414141414141",
193			"C3304FA46097CBBA59085416764A217A5427BBD4A4D50776989441370E3B5B16",
194			true,
195			AESCBCPadder,
196		},
197		{
198			"11111111111111111111111111111111",
199			"22222222222222222222222222222222",
200			"414141414141414141414141414141414141",
201			"C3304FA46097CBBA59085416764A217A7FF985F55567D1B25EA40E23BB4CB1FE",
202			true,
203			AESCBCPadder,
204		},
205		{
206			"11111111111111111111111111111111",
207			"22222222222222222222222222222222",
208			"41414141414141414141414141414141414141",
209			"C3304FA46097CBBA59085416764A217A0835E548C7370D8F8D9925C0E6B54727",
210			true,
211			AESCBCPadder,
212		},
213		{
214			"11111111111111111111111111111111",
215			"22222222222222222222222222222222",
216			"4141414141414141414141414141414141414141",
217			"C3304FA46097CBBA59085416764A217ADC0CF1436399E67BC1122B31CB596649",
218			true,
219			AESCBCPadder,
220		},
221		{
222			"11111111111111111111111111111111",
223			"22222222222222222222222222222222",
224			"414141414141414141414141414141414141414141",
225			"C3304FA46097CBBA59085416764A217A3D096F0DEAFF91938B82E5D404B0B065",
226			true,
227			AESCBCPadder,
228		},
229		{
230			"11111111111111111111111111111111",
231			"22222222222222222222222222222222",
232			"41414141414141414141414141414141414141414141",
233			"C3304FA46097CBBA59085416764A217AD56ABA897A355CF307CCB74226243192",
234			true,
235			AESCBCPadder,
236		},
237		{
238			"11111111111111111111111111111111",
239			"22222222222222222222222222222222",
240			"4141414141414141414141414141414141414141414141",
241			"C3304FA46097CBBA59085416764A217A151284F950B1B1DBCAD6D9E7900DF4E6",
242			true,
243			AESCBCPadder,
244		},
245		{
246			"11111111111111111111111111111111",
247			"22222222222222222222222222222222",
248			"414141414141414141414141414141414141414141414141",
249			"C3304FA46097CBBA59085416764A217AEF85A612514121C299A1D87116C4A182",
250			true,
251			AESCBCPadder,
252		},
253		{
254			"11111111111111111111111111111111",
255			"22222222222222222222222222222222",
256			"41414141414141414141414141414141414141414141414141",
257			"C3304FA46097CBBA59085416764A217A67F157569BFB4013EA3AD16DB8C69AD6",
258			true,
259			AESCBCPadder,
260		},
261		{
262			"11111111111111111111111111111111",
263			"22222222222222222222222222222222",
264			"4141414141414141414141414141414141414141414141414141",
265			"C3304FA46097CBBA59085416764A217AF8520D191F6ACBD88B2140588B91C697",
266			true,
267			AESCBCPadder,
268		},
269		{
270			"11111111111111111111111111111111",
271			"22222222222222222222222222222222",
272			"414141414141414141414141414141414141414141414141414141",
273			"C3304FA46097CBBA59085416764A217ADD8BBAA71745669B96F2683E2F5AEC35",
274			true,
275			AESCBCPadder,
276		},
277		{
278			"11111111111111111111111111111111",
279			"22222222222222222222222222222222",
280			"41414141414141414141414141414141414141414141414141414141",
281			"C3304FA46097CBBA59085416764A217AFB2D4282817D7EC6B33EFAD7AA14A3C5",
282			true,
283			AESCBCPadder,
284		},
285		{
286			"11111111111111111111111111111111",
287			"22222222222222222222222222222222",
288			"4141414141414141414141414141414141414141414141414141414141",
289			"C3304FA46097CBBA59085416764A217A459B89E7E0DAF3DA654576B60B2DA7CE",
290			true,
291			AESCBCPadder,
292		},
293		{
294			"11111111111111111111111111111111",
295			"22222222222222222222222222222222",
296			"414141414141414141414141414141414141414141414141414141414141",
297			"C3304FA46097CBBA59085416764A217A65759F23F9789D05B23D5DBAA9E32036",
298			true,
299			AESCBCPadder,
300		},
301		{
302			"11111111111111111111111111111111",
303			"22222222222222222222222222222222",
304			"41414141414141414141414141414141414141414141414141414141414141",
305			"C3304FA46097CBBA59085416764A217A03C78FBD5E2CB08B3B6D181E23FBDE79",
306			true,
307			AESCBCPadder,
308		},
309		{
310			"11111111111111111111111111111111",
311			"22222222222222222222222222222222",
312			"4141414141414141414141414141414141414141414141414141414141414141",
313			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA013D941FBBDE56C106C482CD022F290F",
314			true,
315			AESCBCPadder,
316		},
317		{
318			"11111111111111111111111111111111",
319			"22222222222222222222222222222222",
320			"414141414141414141414141414141414141414141414141414141414141414141",
321			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA0645D313AC3C29B79DB1AA2E00A5B393",
322			true,
323			AESCBCPadder,
324		},
325		{
326			"11111111111111111111111111111111",
327			"22222222222222222222222222222222",
328			"41414141414141414141414141414141414141414141414141414141414141414141",
329			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA2ED0FD8048053BF22EBE501D82C4B3F1",
330			true,
331			AESCBCPadder,
332		},
333		{
334			"11111111111111111111111111111111",
335			"22222222222222222222222222222222",
336			"4141414141414141414141414141414141414141414141414141414141414141414141",
337			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CAC57D706C7866A01D6E913F98AE57EE54",
338			true,
339			AESCBCPadder,
340		},
341		{
342			"11111111111111111111111111111111",
343			"22222222222222222222222222222222",
344			"414141414141414141414141414141414141414141414141414141414141414141414141",
345			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CAB7FC1241FAFDFE45C4FF982D5DC1DAEF",
346			true,
347			AESCBCPadder,
348		},
349		{
350			"11111111111111111111111111111111",
351			"22222222222222222222222222222222",
352			"41414141414141414141414141414141414141414141414141414141414141414141414141",
353			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA7063EA296922DE8BDFD3B29D786C5F91",
354			true,
355			AESCBCPadder,
356		},
357		{
358			"11111111111111111111111111111111",
359			"22222222222222222222222222222222",
360			"4141414141414141414141414141414141414141414141414141414141414141414141414141",
361			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA3A4603475F4AFDBFADC6E7FA908188B1",
362			true,
363			AESCBCPadder,
364		},
365		{
366			"11111111111111111111111111111111",
367			"22222222222222222222222222222222",
368			"414141414141414141414141414141414141414141414141414141414141414141414141414141",
369			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA3365C63C2AF2A6C8FB4D0E9ED3C6FDA3",
370			true,
371			AESCBCPadder,
372		},
373		{
374			"11111111111111111111111111111111",
375			"22222222222222222222222222222222",
376			"41414141414141414141414141414141414141414141414141414141414141414141414141414141",
377			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA78BCC1874C0B7EB52645FC8F03B9C9CF",
378			true,
379			AESCBCPadder,
380		},
381		{
382			"11111111111111111111111111111111",
383			"22222222222222222222222222222222",
384			"4141414141414141414141414141414141414141414141414141414141414141414141414141414141",
385			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA9B7A31397718EECB89B9E9CCCD729326",
386			true,
387			AESCBCPadder,
388		},
389		{
390			"11111111111111111111111111111111",
391			"22222222222222222222222222222222",
392			"414141414141414141414141414141414141414141414141414141414141414141414141414141414141",
393			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CAB15EA8A67E9E9FADB4249710277F3D4F",
394			true,
395			AESCBCPadder,
396		},
397		{
398			"11111111111111111111111111111111",
399			"22222222222222222222222222222222",
400			"41414141414141414141414141414141414141414141414141414141414141414141414141414141414141",
401			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA94641D6A076193C660632CEA3F9CB02C",
402			true,
403			AESCBCPadder,
404		},
405		{
406			"11111111111111111111111111111111",
407			"22222222222222222222222222222222",
408			"4141414141414141414141414141414141414141414141414141414141414141414141414141414141414141",
409			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CAB2170A08417BE77F0EAA9110F4790E12",
410			true,
411			AESCBCPadder,
412		},
413		{
414			"11111111111111111111111111111111",
415			"22222222222222222222222222222222",
416			"414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141",
417			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA4E30F1CD7B2256ABD57DC3DAB05376C9",
418			true,
419			AESCBCPadder,
420		},
421		{
422			"11111111111111111111111111111111",
423			"22222222222222222222222222222222",
424			"41414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141",
425			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA9909B7B93D01BDAAC22D15AF34DF1EEF",
426			true,
427			AESCBCPadder,
428		},
429		{
430			"11111111111111111111111111111111",
431			"22222222222222222222222222222222",
432			"4141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141",
433			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CAD97F5D1206F00E5C7225CAD81CCD4027",
434			true,
435			AESCBCPadder,
436		},
437		{
438			"11111111111111111111111111111111",
439			"22222222222222222222222222222222",
440			"414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141",
441			"C3304FA46097CBBA59085416764A217ACEF79EE1163A2F52888F87A3979EB3CA570CBB001A0C87558906B60C884AB5F41DA97CEF2A9401BC6DD0D22A54DBAD6D",
442			true,
443			AESCBCPadder,
444		},
445	}
446
447	for i, testCase := range testCases {
448		key, _ := hex.DecodeString(testCase.key)
449		iv, _ := hex.DecodeString(testCase.iv)
450		cd := CipherData{
451			Key: key,
452			IV:  iv,
453		}
454
455		cbc, err := newAESCBC(cd, testCase.padder)
456		if err != nil {
457			t.Fatal(fmt.Sprintf("Case %d: Expected no error for cipher creation, but received: %v", i, err.Error()))
458		}
459
460		plaintext := []byte(testCase.plaintext)
461		if testCase.decodeHex {
462			plaintext, _ = hex.DecodeString(testCase.plaintext)
463		}
464
465		cipherdata := cbc.Encrypt(bytes.NewReader(plaintext))
466		ciphertext := []byte{}
467		b := make([]byte, 19)
468		err = nil
469		n := 0
470		for err != io.EOF {
471			n, err = cipherdata.Read(b)
472			ciphertext = append(ciphertext, b[:n]...)
473		}
474
475		if err != io.EOF {
476			t.Fatal(fmt.Sprintf("Case %d: Expected no error during io reading, but received: %v", i, err.Error()))
477		}
478
479		expectedData, _ := hex.DecodeString(testCase.ciphertext)
480		if bytes.Compare(expectedData, ciphertext) != 0 {
481			t.Log("\n", ciphertext, "\n", expectedData)
482			t.Fatal(fmt.Sprintf("Case %d: AES CBC encryption fails. Data is not the same", i))
483		}
484
485		plaindata := cbc.Decrypt(bytes.NewReader(ciphertext))
486		plaintextDecrypted := []byte{}
487		err = nil
488		for err != io.EOF {
489			n, err = plaindata.Read(b)
490			plaintextDecrypted = append(plaintextDecrypted, b[:n]...)
491		}
492		if err != io.EOF {
493			t.Fatal(fmt.Sprintf("Case %d: Expected no error during io reading, but received: %v", i, err.Error()))
494		}
495
496		if bytes.Compare(plaintext, plaintextDecrypted) != 0 {
497			t.Log("\n", plaintext, "\n", plaintextDecrypted)
498			t.Fatal(fmt.Sprintf("Case %d: AES CBC decryption fails. Data is not the same", i))
499		}
500	}
501}
502