test_CBC.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  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 tls.Crypto.SelfTest.loader import load_tests
  33. from tls.Crypto.SelfTest.st_common import list_test_cases
  34. from tls.Crypto.Util.py3compat import tobytes, _memoryview, is_string
  35. from tls.Crypto.Cipher import AES, DES3, DES
  36. from tls.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. import sys
  239. if sys.version[:3] == "2.6":
  240. del test_memoryview
  241. del test_output_param_memoryview
  242. class CbcTests(BlockChainingTests):
  243. aes_mode = AES.MODE_CBC
  244. des3_mode = DES3.MODE_CBC
  245. class NistBlockChainingVectors(unittest.TestCase):
  246. def _do_kat_aes_test(self, file_name):
  247. test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
  248. file_name,
  249. "AES KAT",
  250. { "count" : lambda x: int(x) } )
  251. assert(test_vectors)
  252. direction = None
  253. for tv in test_vectors:
  254. # The test vector file contains some directive lines
  255. if is_string(tv):
  256. direction = tv
  257. continue
  258. self.description = tv.desc
  259. cipher = AES.new(tv.key, self.aes_mode, tv.iv)
  260. if direction == "[ENCRYPT]":
  261. self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext)
  262. elif direction == "[DECRYPT]":
  263. self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext)
  264. else:
  265. assert False
  266. # See Section 6.4.2 in AESAVS
  267. def _do_mct_aes_test(self, file_name):
  268. test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "AES"),
  269. file_name,
  270. "AES Montecarlo",
  271. { "count" : lambda x: int(x) } )
  272. assert(test_vectors)
  273. direction = None
  274. for tv in test_vectors:
  275. # The test vector file contains some directive lines
  276. if is_string(tv):
  277. direction = tv
  278. continue
  279. self.description = tv.desc
  280. cipher = AES.new(tv.key, self.aes_mode, tv.iv)
  281. if direction == '[ENCRYPT]':
  282. cts = [ tv.iv ]
  283. for count in range(1000):
  284. cts.append(cipher.encrypt(tv.plaintext))
  285. tv.plaintext = cts[-2]
  286. self.assertEqual(cts[-1], tv.ciphertext)
  287. elif direction == '[DECRYPT]':
  288. pts = [ tv.iv]
  289. for count in range(1000):
  290. pts.append(cipher.decrypt(tv.ciphertext))
  291. tv.ciphertext = pts[-2]
  292. self.assertEqual(pts[-1], tv.plaintext)
  293. else:
  294. assert False
  295. def _do_tdes_test(self, file_name):
  296. test_vectors = load_tests(("Crypto", "SelfTest", "Cipher", "test_vectors", "TDES"),
  297. file_name,
  298. "TDES CBC KAT",
  299. { "count" : lambda x: int(x) } )
  300. assert(test_vectors)
  301. direction = None
  302. for tv in test_vectors:
  303. # The test vector file contains some directive lines
  304. if is_string(tv):
  305. direction = tv
  306. continue
  307. self.description = tv.desc
  308. if hasattr(tv, "keys"):
  309. cipher = DES.new(tv.keys, self.des_mode, tv.iv)
  310. else:
  311. if tv.key1 != tv.key3:
  312. key = tv.key1 + tv.key2 + tv.key3 # Option 3
  313. else:
  314. key = tv.key1 + tv.key2 # Option 2
  315. cipher = DES3.new(key, self.des3_mode, tv.iv)
  316. if direction == "[ENCRYPT]":
  317. self.assertEqual(cipher.encrypt(tv.plaintext), tv.ciphertext)
  318. elif direction == "[DECRYPT]":
  319. self.assertEqual(cipher.decrypt(tv.ciphertext), tv.plaintext)
  320. else:
  321. assert False
  322. class NistCbcVectors(NistBlockChainingVectors):
  323. aes_mode = AES.MODE_CBC
  324. des_mode = DES.MODE_CBC
  325. des3_mode = DES3.MODE_CBC
  326. # Create one test method per file
  327. nist_aes_kat_mmt_files = (
  328. # KAT
  329. "CBCGFSbox128.rsp",
  330. "CBCGFSbox192.rsp",
  331. "CBCGFSbox256.rsp",
  332. "CBCKeySbox128.rsp",
  333. "CBCKeySbox192.rsp",
  334. "CBCKeySbox256.rsp",
  335. "CBCVarKey128.rsp",
  336. "CBCVarKey192.rsp",
  337. "CBCVarKey256.rsp",
  338. "CBCVarTxt128.rsp",
  339. "CBCVarTxt192.rsp",
  340. "CBCVarTxt256.rsp",
  341. # MMT
  342. "CBCMMT128.rsp",
  343. "CBCMMT192.rsp",
  344. "CBCMMT256.rsp",
  345. )
  346. nist_aes_mct_files = (
  347. "CBCMCT128.rsp",
  348. "CBCMCT192.rsp",
  349. "CBCMCT256.rsp",
  350. )
  351. for file_name in nist_aes_kat_mmt_files:
  352. def new_func(self, file_name=file_name):
  353. self._do_kat_aes_test(file_name)
  354. setattr(NistCbcVectors, "test_AES_" + file_name, new_func)
  355. for file_name in nist_aes_mct_files:
  356. def new_func(self, file_name=file_name):
  357. self._do_mct_aes_test(file_name)
  358. setattr(NistCbcVectors, "test_AES_" + file_name, new_func)
  359. del file_name, new_func
  360. nist_tdes_files = (
  361. "TCBCMMT2.rsp", # 2TDES
  362. "TCBCMMT3.rsp", # 3TDES
  363. "TCBCinvperm.rsp", # Single DES
  364. "TCBCpermop.rsp",
  365. "TCBCsubtab.rsp",
  366. "TCBCvarkey.rsp",
  367. "TCBCvartext.rsp",
  368. )
  369. for file_name in nist_tdes_files:
  370. def new_func(self, file_name=file_name):
  371. self._do_tdes_test(file_name)
  372. setattr(NistCbcVectors, "test_TDES_" + file_name, new_func)
  373. # END OF NIST CBC TEST VECTORS
  374. class SP800TestVectors(unittest.TestCase):
  375. """Class exercising the CBC test vectors found in Section F.2
  376. of NIST SP 800-3A"""
  377. def test_aes_128(self):
  378. key = '2b7e151628aed2a6abf7158809cf4f3c'
  379. iv = '000102030405060708090a0b0c0d0e0f'
  380. plaintext = '6bc1bee22e409f96e93d7e117393172a' +\
  381. 'ae2d8a571e03ac9c9eb76fac45af8e51' +\
  382. '30c81c46a35ce411e5fbc1191a0a52ef' +\
  383. 'f69f2445df4f9b17ad2b417be66c3710'
  384. ciphertext = '7649abac8119b246cee98e9b12e9197d' +\
  385. '5086cb9b507219ee95db113a917678b2' +\
  386. '73bed6b8e3c1743b7116e69e22229516' +\
  387. '3ff1caa1681fac09120eca307586e1a7'
  388. key = unhexlify(key)
  389. iv = unhexlify(iv)
  390. plaintext = unhexlify(plaintext)
  391. ciphertext = unhexlify(ciphertext)
  392. cipher = AES.new(key, AES.MODE_CBC, iv)
  393. self.assertEqual(cipher.encrypt(plaintext), ciphertext)
  394. cipher = AES.new(key, AES.MODE_CBC, iv)
  395. self.assertEqual(cipher.decrypt(ciphertext), plaintext)
  396. def test_aes_192(self):
  397. key = '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'
  398. iv = '000102030405060708090a0b0c0d0e0f'
  399. plaintext = '6bc1bee22e409f96e93d7e117393172a' +\
  400. 'ae2d8a571e03ac9c9eb76fac45af8e51' +\
  401. '30c81c46a35ce411e5fbc1191a0a52ef' +\
  402. 'f69f2445df4f9b17ad2b417be66c3710'
  403. ciphertext = '4f021db243bc633d7178183a9fa071e8' +\
  404. 'b4d9ada9ad7dedf4e5e738763f69145a' +\
  405. '571b242012fb7ae07fa9baac3df102e0' +\
  406. '08b0e27988598881d920a9e64f5615cd'
  407. key = unhexlify(key)
  408. iv = unhexlify(iv)
  409. plaintext = unhexlify(plaintext)
  410. ciphertext = unhexlify(ciphertext)
  411. cipher = AES.new(key, AES.MODE_CBC, iv)
  412. self.assertEqual(cipher.encrypt(plaintext), ciphertext)
  413. cipher = AES.new(key, AES.MODE_CBC, iv)
  414. self.assertEqual(cipher.decrypt(ciphertext), plaintext)
  415. def test_aes_256(self):
  416. key = '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4'
  417. iv = '000102030405060708090a0b0c0d0e0f'
  418. plaintext = '6bc1bee22e409f96e93d7e117393172a' +\
  419. 'ae2d8a571e03ac9c9eb76fac45af8e51' +\
  420. '30c81c46a35ce411e5fbc1191a0a52ef' +\
  421. 'f69f2445df4f9b17ad2b417be66c3710'
  422. ciphertext = 'f58c4c04d6e5f1ba779eabfb5f7bfbd6' +\
  423. '9cfc4e967edb808d679f777bc6702c7d' +\
  424. '39f23369a9d9bacfa530e26304231461' +\
  425. 'b2eb05e2c39be9fcda6c19078c6a9d1b'
  426. key = unhexlify(key)
  427. iv = unhexlify(iv)
  428. plaintext = unhexlify(plaintext)
  429. ciphertext = unhexlify(ciphertext)
  430. cipher = AES.new(key, AES.MODE_CBC, iv)
  431. self.assertEqual(cipher.encrypt(plaintext), ciphertext)
  432. cipher = AES.new(key, AES.MODE_CBC, iv)
  433. self.assertEqual(cipher.decrypt(ciphertext), plaintext)
  434. def get_tests(config={}):
  435. tests = []
  436. tests += list_test_cases(CbcTests)
  437. if config.get('slow_tests'):
  438. tests += list_test_cases(NistCbcVectors)
  439. tests += list_test_cases(SP800TestVectors)
  440. return tests
  441. if __name__ == '__main__':
  442. suite = lambda: unittest.TestSuite(get_tests())
  443. unittest.main(defaultTest='suite')