test_CBC.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. # ===================================================================
  2. #
  3. # Copyright (c) 2014, Legrandin <helderijs@gmail.com>
  4. # All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. #
  10. # 1. Redistributions of source code must retain the above copyright
  11. # notice, this list of conditions and the following disclaimer.
  12. # 2. Redistributions in binary form must reproduce the above copyright
  13. # notice, this list of conditions and the following disclaimer in
  14. # the documentation and/or other materials provided with the
  15. # distribution.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  27. # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  28. # POSSIBILITY OF SUCH DAMAGE.
  29. # ===================================================================
  30. import unittest
  31. from binascii import unhexlify
  32. from Crypto.SelfTest.loader import load_test_vectors
  33. from Crypto.SelfTest.st_common import list_test_cases
  34. from Crypto.Util.py3compat import tobytes, is_string
  35. from Crypto.Cipher import AES, DES3, DES
  36. from Crypto.Hash import SHAKE128
  37. def get_tag_random(tag, length):
  38. return SHAKE128.new(data=tobytes(tag)).read(length)
  39. class BlockChainingTests(unittest.TestCase):
  40. key_128 = get_tag_random("key_128", 16)
  41. key_192 = get_tag_random("key_192", 24)
  42. iv_128 = get_tag_random("iv_128", 16)
  43. iv_64 = get_tag_random("iv_64", 8)
  44. data_128 = get_tag_random("data_128", 16)
  45. def test_loopback_128(self):
  46. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  47. pt = get_tag_random("plaintext", 16 * 100)
  48. ct = cipher.encrypt(pt)
  49. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  50. pt2 = cipher.decrypt(ct)
  51. self.assertEqual(pt, pt2)
  52. def test_loopback_64(self):
  53. cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
  54. pt = get_tag_random("plaintext", 8 * 100)
  55. ct = cipher.encrypt(pt)
  56. cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
  57. pt2 = cipher.decrypt(ct)
  58. self.assertEqual(pt, pt2)
  59. def test_iv(self):
  60. # If not passed, the iv is created randomly
  61. cipher = AES.new(self.key_128, self.aes_mode)
  62. iv1 = cipher.iv
  63. cipher = AES.new(self.key_128, self.aes_mode)
  64. iv2 = cipher.iv
  65. self.assertNotEqual(iv1, iv2)
  66. self.assertEqual(len(iv1), 16)
  67. # IV can be passed in uppercase or lowercase
  68. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  69. ct = cipher.encrypt(self.data_128)
  70. cipher = AES.new(self.key_128, self.aes_mode, iv=self.iv_128)
  71. self.assertEquals(ct, cipher.encrypt(self.data_128))
  72. cipher = AES.new(self.key_128, self.aes_mode, IV=self.iv_128)
  73. self.assertEquals(ct, cipher.encrypt(self.data_128))
  74. def test_iv_must_be_bytes(self):
  75. self.assertRaises(TypeError, AES.new, self.key_128, self.aes_mode,
  76. iv = u'test1234567890-*')
  77. def test_only_one_iv(self):
  78. # Only one IV/iv keyword allowed
  79. self.assertRaises(TypeError, AES.new, self.key_128, self.aes_mode,
  80. iv=self.iv_128, IV=self.iv_128)
  81. def test_iv_with_matching_length(self):
  82. self.assertRaises(ValueError, AES.new, self.key_128, self.aes_mode,
  83. b"")
  84. self.assertRaises(ValueError, AES.new, self.key_128, self.aes_mode,
  85. self.iv_128[:15])
  86. self.assertRaises(ValueError, AES.new, self.key_128, self.aes_mode,
  87. self.iv_128 + b"0")
  88. def test_block_size_128(self):
  89. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  90. self.assertEqual(cipher.block_size, AES.block_size)
  91. def test_block_size_64(self):
  92. cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
  93. self.assertEqual(cipher.block_size, DES3.block_size)
  94. def test_unaligned_data_128(self):
  95. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  96. for wrong_length in range(1,16):
  97. self.assertRaises(ValueError, cipher.encrypt, b"5" * wrong_length)
  98. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  99. for wrong_length in range(1,16):
  100. self.assertRaises(ValueError, cipher.decrypt, b"5" * wrong_length)
  101. def test_unaligned_data_64(self):
  102. cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
  103. for wrong_length in range(1,8):
  104. self.assertRaises(ValueError, cipher.encrypt, b"5" * wrong_length)
  105. cipher = DES3.new(self.key_192, self.des3_mode, self.iv_64)
  106. for wrong_length in range(1,8):
  107. self.assertRaises(ValueError, cipher.decrypt, b"5" * wrong_length)
  108. def test_IV_iv_attributes(self):
  109. data = get_tag_random("data", 16 * 100)
  110. for func in "encrypt", "decrypt":
  111. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  112. getattr(cipher, func)(data)
  113. self.assertEqual(cipher.iv, self.iv_128)
  114. self.assertEqual(cipher.IV, self.iv_128)
  115. def test_unknown_parameters(self):
  116. self.assertRaises(TypeError, AES.new, self.key_128, self.aes_mode,
  117. self.iv_128, 7)
  118. self.assertRaises(TypeError, AES.new, self.key_128, self.aes_mode,
  119. iv=self.iv_128, unknown=7)
  120. # But some are only known by the base cipher (e.g. use_aesni consumed by the AES module)
  121. AES.new(self.key_128, self.aes_mode, iv=self.iv_128, use_aesni=False)
  122. def test_null_encryption_decryption(self):
  123. for func in "encrypt", "decrypt":
  124. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  125. result = getattr(cipher, func)(b"")
  126. self.assertEqual(result, b"")
  127. def test_either_encrypt_or_decrypt(self):
  128. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  129. cipher.encrypt(b"")
  130. self.assertRaises(TypeError, cipher.decrypt, b"")
  131. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  132. cipher.decrypt(b"")
  133. self.assertRaises(TypeError, cipher.encrypt, b"")
  134. def test_data_must_be_bytes(self):
  135. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  136. self.assertRaises(TypeError, cipher.encrypt, u'test1234567890-*')
  137. cipher = AES.new(self.key_128, self.aes_mode, self.iv_128)
  138. self.assertRaises(TypeError, cipher.decrypt, u'test1234567890-*')
  139. def test_bytearray(self):
  140. data = b"1" * 16
  141. data_ba = bytearray(data)
  142. # Encrypt
  143. key_ba = bytearray(self.key_128)
  144. iv_ba = bytearray(self.iv_128)
  145. cipher1 = AES.new(self.key_128, self.aes_mode, self.iv_128)
  146. ref1 = cipher1.encrypt(data)
  147. cipher2 = AES.new(key_ba, self.aes_mode, iv_ba)
  148. key_ba[:3] = b'\xFF\xFF\xFF'
  149. iv_ba[:3] = b'\xFF\xFF\xFF'
  150. ref2 = cipher2.encrypt(data_ba)
  151. self.assertEqual(ref1, ref2)
  152. self.assertEqual(cipher1.iv, cipher2.iv)
  153. # Decrypt
  154. key_ba = bytearray(self.key_128)
  155. iv_ba = bytearray(self.iv_128)
  156. cipher3 = AES.new(self.key_128, self.aes_mode, self.iv_128)
  157. ref3 = cipher3.decrypt(data)
  158. cipher4 = AES.new(key_ba, self.aes_mode, iv_ba)
  159. key_ba[:3] = b'\xFF\xFF\xFF'
  160. iv_ba[:3] = b'\xFF\xFF\xFF'
  161. ref4 = cipher4.decrypt(data_ba)
  162. self.assertEqual(ref3, ref4)
  163. def test_memoryview(self):
  164. data = b"1" * 16
  165. data_mv = memoryview(bytearray(data))
  166. # Encrypt
  167. key_mv = memoryview(bytearray(self.key_128))
  168. iv_mv = memoryview(bytearray(self.iv_128))
  169. cipher1 = AES.new(self.key_128, self.aes_mode, self.iv_128)
  170. ref1 = cipher1.encrypt(data)
  171. cipher2 = AES.new(key_mv, self.aes_mode, iv_mv)
  172. key_mv[:3] = b'\xFF\xFF\xFF'
  173. iv_mv[:3] = b'\xFF\xFF\xFF'
  174. ref2 = cipher2.encrypt(data_mv)
  175. self.assertEqual(ref1, ref2)
  176. self.assertEqual(cipher1.iv, cipher2.iv)
  177. # Decrypt
  178. key_mv = memoryview(bytearray(self.key_128))
  179. iv_mv = memoryview(bytearray(self.iv_128))
  180. cipher3 = AES.new(self.key_128, self.aes_mode, self.iv_128)
  181. ref3 = cipher3.decrypt(data)
  182. cipher4 = AES.new(key_mv, self.aes_mode, iv_mv)
  183. key_mv[:3] = b'\xFF\xFF\xFF'
  184. iv_mv[:3] = b'\xFF\xFF\xFF'
  185. ref4 = cipher4.decrypt(data_mv)
  186. self.assertEqual(ref3, ref4)
  187. def test_output_param(self):
  188. pt = b'5' * 16
  189. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  190. ct = cipher.encrypt(pt)
  191. output = bytearray(16)
  192. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  193. res = cipher.encrypt(pt, output=output)
  194. self.assertEqual(ct, output)
  195. self.assertEqual(res, None)
  196. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  197. res = cipher.decrypt(ct, output=output)
  198. self.assertEqual(pt, output)
  199. self.assertEqual(res, None)
  200. def test_output_param_same_buffer(self):
  201. pt = b'5' * 16
  202. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  203. ct = cipher.encrypt(pt)
  204. pt_ba = bytearray(pt)
  205. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  206. res = cipher.encrypt(pt_ba, output=pt_ba)
  207. self.assertEqual(ct, pt_ba)
  208. self.assertEqual(res, None)
  209. ct_ba = bytearray(ct)
  210. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  211. res = cipher.decrypt(ct_ba, output=ct_ba)
  212. self.assertEqual(pt, ct_ba)
  213. self.assertEqual(res, None)
  214. def test_output_param_memoryview(self):
  215. pt = b'5' * 16
  216. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  217. ct = cipher.encrypt(pt)
  218. output = memoryview(bytearray(16))
  219. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  220. cipher.encrypt(pt, output=output)
  221. self.assertEqual(ct, output)
  222. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  223. cipher.decrypt(ct, output=output)
  224. self.assertEqual(pt, output)
  225. def test_output_param_neg(self):
  226. pt = b'5' * 16
  227. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  228. ct = cipher.encrypt(pt)
  229. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  230. self.assertRaises(TypeError, cipher.encrypt, pt, output=b'0'*16)
  231. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  232. self.assertRaises(TypeError, cipher.decrypt, ct, output=b'0'*16)
  233. shorter_output = bytearray(15)
  234. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  235. self.assertRaises(ValueError, cipher.encrypt, pt, output=shorter_output)
  236. cipher = AES.new(b'4'*16, self.aes_mode, iv=self.iv_128)
  237. self.assertRaises(ValueError, cipher.decrypt, ct, output=shorter_output)
  238. class CbcTests(BlockChainingTests):
  239. aes_mode = AES.MODE_CBC
  240. des3_mode = DES3.MODE_CBC
  241. class NistBlockChainingVectors(unittest.TestCase):
  242. def _do_kat_aes_test(self, file_name):
  243. test_vectors = load_test_vectors(("Cipher", "AES"),
  244. file_name,
  245. "AES CBC KAT",
  246. { "count" : lambda x: int(x) } )
  247. if test_vectors is None:
  248. return
  249. direction = None
  250. for tv in test_vectors:
  251. # The test vector file contains some directive lines
  252. if is_string(tv):
  253. direction = tv
  254. continue
  255. self.description = tv.desc
  256. cipher = AES.new(tv.key, self.aes_mode, tv.iv)
  257. if direction == "[ENCRYPT]":
  258. self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext)
  259. elif direction == "[DECRYPT]":
  260. self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext)
  261. else:
  262. assert False
  263. # See Section 6.4.2 in AESAVS
  264. def _do_mct_aes_test(self, file_name):
  265. test_vectors = load_test_vectors(("Cipher", "AES"),
  266. file_name,
  267. "AES CBC Montecarlo",
  268. { "count" : lambda x: int(x) } )
  269. if test_vectors is None:
  270. return
  271. direction = None
  272. for tv in test_vectors:
  273. # The test vector file contains some directive lines
  274. if is_string(tv):
  275. direction = tv
  276. continue
  277. self.description = tv.desc
  278. cipher = AES.new(tv.key, self.aes_mode, tv.iv)
  279. if direction == '[ENCRYPT]':
  280. cts = [ tv.iv ]
  281. for count in range(1000):
  282. cts.append(cipher.encrypt(tv.plaintext))
  283. tv.plaintext = cts[-2]
  284. self.assertEqual(cts[-1], tv.ciphertext)
  285. elif direction == '[DECRYPT]':
  286. pts = [ tv.iv]
  287. for count in range(1000):
  288. pts.append(cipher.decrypt(tv.ciphertext))
  289. tv.ciphertext = pts[-2]
  290. self.assertEqual(pts[-1], tv.plaintext)
  291. else:
  292. assert False
  293. def _do_tdes_test(self, file_name):
  294. test_vectors = load_test_vectors(("Cipher", "TDES"),
  295. file_name,
  296. "TDES CBC KAT",
  297. { "count" : lambda x: int(x) } )
  298. if test_vectors is None:
  299. return
  300. direction = None
  301. for tv in test_vectors:
  302. # The test vector file contains some directive lines
  303. if is_string(tv):
  304. direction = tv
  305. continue
  306. self.description = tv.desc
  307. if hasattr(tv, "keys"):
  308. cipher = DES.new(tv.keys, self.des_mode, tv.iv)
  309. else:
  310. if tv.key1 != tv.key3:
  311. key = tv.key1 + tv.key2 + tv.key3 # Option 3
  312. else:
  313. key = tv.key1 + tv.key2 # Option 2
  314. cipher = DES3.new(key, self.des3_mode, tv.iv)
  315. if direction == "[ENCRYPT]":
  316. self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext)
  317. elif direction == "[DECRYPT]":
  318. self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext)
  319. else:
  320. assert False
  321. class NistCbcVectors(NistBlockChainingVectors):
  322. aes_mode = AES.MODE_CBC
  323. des_mode = DES.MODE_CBC
  324. des3_mode = DES3.MODE_CBC
  325. # Create one test method per file
  326. nist_aes_kat_mmt_files = (
  327. # KAT
  328. "CBCGFSbox128.rsp",
  329. "CBCGFSbox192.rsp",
  330. "CBCGFSbox256.rsp",
  331. "CBCKeySbox128.rsp",
  332. "CBCKeySbox192.rsp",
  333. "CBCKeySbox256.rsp",
  334. "CBCVarKey128.rsp",
  335. "CBCVarKey192.rsp",
  336. "CBCVarKey256.rsp",
  337. "CBCVarTxt128.rsp",
  338. "CBCVarTxt192.rsp",
  339. "CBCVarTxt256.rsp",
  340. # MMT
  341. "CBCMMT128.rsp",
  342. "CBCMMT192.rsp",
  343. "CBCMMT256.rsp",
  344. )
  345. nist_aes_mct_files = (
  346. "CBCMCT128.rsp",
  347. "CBCMCT192.rsp",
  348. "CBCMCT256.rsp",
  349. )
  350. for file_name in nist_aes_kat_mmt_files:
  351. def new_func(self, file_name=file_name):
  352. self._do_kat_aes_test(file_name)
  353. setattr(NistCbcVectors, "test_AES_" + file_name, new_func)
  354. for file_name in nist_aes_mct_files:
  355. def new_func(self, file_name=file_name):
  356. self._do_mct_aes_test(file_name)
  357. setattr(NistCbcVectors, "test_AES_" + file_name, new_func)
  358. del file_name, new_func
  359. nist_tdes_files = (
  360. "TCBCMMT2.rsp", # 2TDES
  361. "TCBCMMT3.rsp", # 3TDES
  362. "TCBCinvperm.rsp", # Single DES
  363. "TCBCpermop.rsp",
  364. "TCBCsubtab.rsp",
  365. "TCBCvarkey.rsp",
  366. "TCBCvartext.rsp",
  367. )
  368. for file_name in nist_tdes_files:
  369. def new_func(self, file_name=file_name):
  370. self._do_tdes_test(file_name)
  371. setattr(NistCbcVectors, "test_TDES_" + file_name, new_func)
  372. # END OF NIST CBC TEST VECTORS
  373. class SP800TestVectors(unittest.TestCase):
  374. """Class exercising the CBC test vectors found in Section F.2
  375. of NIST SP 800-3A"""
  376. def test_aes_128(self):
  377. key = '2b7e151628aed2a6abf7158809cf4f3c'
  378. iv = '000102030405060708090a0b0c0d0e0f'
  379. plaintext = '6bc1bee22e409f96e93d7e117393172a' +\
  380. 'ae2d8a571e03ac9c9eb76fac45af8e51' +\
  381. '30c81c46a35ce411e5fbc1191a0a52ef' +\
  382. 'f69f2445df4f9b17ad2b417be66c3710'
  383. ciphertext = '7649abac8119b246cee98e9b12e9197d' +\
  384. '5086cb9b507219ee95db113a917678b2' +\
  385. '73bed6b8e3c1743b7116e69e22229516' +\
  386. '3ff1caa1681fac09120eca307586e1a7'
  387. key = unhexlify(key)
  388. iv = unhexlify(iv)
  389. plaintext = unhexlify(plaintext)
  390. ciphertext = unhexlify(ciphertext)
  391. cipher = AES.new(key, AES.MODE_CBC, iv)
  392. self.assertEqual(cipher.encrypt(plaintext), ciphertext)
  393. cipher = AES.new(key, AES.MODE_CBC, iv)
  394. self.assertEqual(cipher.decrypt(ciphertext), plaintext)
  395. def test_aes_192(self):
  396. key = '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'
  397. iv = '000102030405060708090a0b0c0d0e0f'
  398. plaintext = '6bc1bee22e409f96e93d7e117393172a' +\
  399. 'ae2d8a571e03ac9c9eb76fac45af8e51' +\
  400. '30c81c46a35ce411e5fbc1191a0a52ef' +\
  401. 'f69f2445df4f9b17ad2b417be66c3710'
  402. ciphertext = '4f021db243bc633d7178183a9fa071e8' +\
  403. 'b4d9ada9ad7dedf4e5e738763f69145a' +\
  404. '571b242012fb7ae07fa9baac3df102e0' +\
  405. '08b0e27988598881d920a9e64f5615cd'
  406. key = unhexlify(key)
  407. iv = unhexlify(iv)
  408. plaintext = unhexlify(plaintext)
  409. ciphertext = unhexlify(ciphertext)
  410. cipher = AES.new(key, AES.MODE_CBC, iv)
  411. self.assertEqual(cipher.encrypt(plaintext), ciphertext)
  412. cipher = AES.new(key, AES.MODE_CBC, iv)
  413. self.assertEqual(cipher.decrypt(ciphertext), plaintext)
  414. def test_aes_256(self):
  415. key = '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4'
  416. iv = '000102030405060708090a0b0c0d0e0f'
  417. plaintext = '6bc1bee22e409f96e93d7e117393172a' +\
  418. 'ae2d8a571e03ac9c9eb76fac45af8e51' +\
  419. '30c81c46a35ce411e5fbc1191a0a52ef' +\
  420. 'f69f2445df4f9b17ad2b417be66c3710'
  421. ciphertext = 'f58c4c04d6e5f1ba779eabfb5f7bfbd6' +\
  422. '9cfc4e967edb808d679f777bc6702c7d' +\
  423. '39f23369a9d9bacfa530e26304231461' +\
  424. 'b2eb05e2c39be9fcda6c19078c6a9d1b'
  425. key = unhexlify(key)
  426. iv = unhexlify(iv)
  427. plaintext = unhexlify(plaintext)
  428. ciphertext = unhexlify(ciphertext)
  429. cipher = AES.new(key, AES.MODE_CBC, iv)
  430. self.assertEqual(cipher.encrypt(plaintext), ciphertext)
  431. cipher = AES.new(key, AES.MODE_CBC, iv)
  432. self.assertEqual(cipher.decrypt(ciphertext), plaintext)
  433. def get_tests(config={}):
  434. tests = []
  435. tests += list_test_cases(CbcTests)
  436. if config.get('slow_tests'):
  437. tests += list_test_cases(NistCbcVectors)
  438. tests += list_test_cases(SP800TestVectors)
  439. return tests
  440. if __name__ == '__main__':
  441. suite = lambda: unittest.TestSuite(get_tests())
  442. unittest.main(defaultTest='suite')