test_OCB.py 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  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.Util.py3compat import b, tobytes, bchr
  33. from Crypto.Util.number import long_to_bytes
  34. from Crypto.SelfTest.loader import load_test_vectors
  35. from Crypto.SelfTest.st_common import list_test_cases
  36. from Crypto.Cipher import AES
  37. from Crypto.Hash import SHAKE128
  38. def get_tag_random(tag, length):
  39. return SHAKE128.new(data=tobytes(tag)).read(length)
  40. class OcbTests(unittest.TestCase):
  41. key_128 = get_tag_random("key_128", 16)
  42. nonce_96 = get_tag_random("nonce_128", 12)
  43. data = get_tag_random("data", 128)
  44. def test_loopback_128(self):
  45. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  46. pt = get_tag_random("plaintext", 16 * 100)
  47. ct, mac = cipher.encrypt_and_digest(pt)
  48. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  49. pt2 = cipher.decrypt_and_verify(ct, mac)
  50. self.assertEqual(pt, pt2)
  51. def test_nonce(self):
  52. # Nonce is optional
  53. AES.new(self.key_128, AES.MODE_OCB)
  54. cipher = AES.new(self.key_128, AES.MODE_OCB, self.nonce_96)
  55. ct = cipher.encrypt(self.data)
  56. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  57. self.assertEqual(ct, cipher.encrypt(self.data))
  58. def test_nonce_must_be_bytes(self):
  59. self.assertRaises(TypeError, AES.new, self.key_128, AES.MODE_OCB,
  60. nonce=u'test12345678')
  61. def test_nonce_length(self):
  62. # nonce cannot be empty
  63. self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_OCB,
  64. nonce=b(""))
  65. # nonce can be up to 15 bytes long
  66. for length in range(1, 16):
  67. AES.new(self.key_128, AES.MODE_OCB, nonce=self.data[:length])
  68. self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_OCB,
  69. nonce=self.data)
  70. def test_block_size_128(self):
  71. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  72. self.assertEqual(cipher.block_size, AES.block_size)
  73. # By default, a 15 bytes long nonce is randomly generated
  74. nonce1 = AES.new(self.key_128, AES.MODE_OCB).nonce
  75. nonce2 = AES.new(self.key_128, AES.MODE_OCB).nonce
  76. self.assertEqual(len(nonce1), 15)
  77. self.assertNotEqual(nonce1, nonce2)
  78. def test_nonce_attribute(self):
  79. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  80. self.assertEqual(cipher.nonce, self.nonce_96)
  81. # By default, a 15 bytes long nonce is randomly generated
  82. nonce1 = AES.new(self.key_128, AES.MODE_OCB).nonce
  83. nonce2 = AES.new(self.key_128, AES.MODE_OCB).nonce
  84. self.assertEqual(len(nonce1), 15)
  85. self.assertNotEqual(nonce1, nonce2)
  86. def test_unknown_parameters(self):
  87. self.assertRaises(TypeError, AES.new, self.key_128, AES.MODE_OCB,
  88. self.nonce_96, 7)
  89. self.assertRaises(TypeError, AES.new, self.key_128, AES.MODE_OCB,
  90. nonce=self.nonce_96, unknown=7)
  91. # But some are only known by the base cipher
  92. # (e.g. use_aesni consumed by the AES module)
  93. AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96,
  94. use_aesni=False)
  95. def test_null_encryption_decryption(self):
  96. for func in "encrypt", "decrypt":
  97. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  98. result = getattr(cipher, func)(b(""))
  99. self.assertEqual(result, b(""))
  100. def test_either_encrypt_or_decrypt(self):
  101. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  102. cipher.encrypt(b("xyz"))
  103. self.assertRaises(TypeError, cipher.decrypt, b("xyz"))
  104. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  105. cipher.decrypt(b("xyz"))
  106. self.assertRaises(TypeError, cipher.encrypt, b("xyz"))
  107. def test_data_must_be_bytes(self):
  108. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  109. self.assertRaises(TypeError, cipher.encrypt, u'test1234567890-*')
  110. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  111. self.assertRaises(TypeError, cipher.decrypt, u'test1234567890-*')
  112. def test_mac_len(self):
  113. # Invalid MAC length
  114. self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_OCB,
  115. nonce=self.nonce_96, mac_len=7)
  116. self.assertRaises(ValueError, AES.new, self.key_128, AES.MODE_OCB,
  117. nonce=self.nonce_96, mac_len=16+1)
  118. # Valid MAC length
  119. for mac_len in range(8, 16 + 1):
  120. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96,
  121. mac_len=mac_len)
  122. _, mac = cipher.encrypt_and_digest(self.data)
  123. self.assertEqual(len(mac), mac_len)
  124. # Default MAC length
  125. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  126. _, mac = cipher.encrypt_and_digest(self.data)
  127. self.assertEqual(len(mac), 16)
  128. def test_invalid_mac(self):
  129. from Crypto.Util.strxor import strxor_c
  130. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  131. ct, mac = cipher.encrypt_and_digest(self.data)
  132. invalid_mac = strxor_c(mac, 0x01)
  133. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  134. self.assertRaises(ValueError, cipher.decrypt_and_verify, ct,
  135. invalid_mac)
  136. def test_hex_mac(self):
  137. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  138. mac_hex = cipher.hexdigest()
  139. self.assertEqual(cipher.digest(), unhexlify(mac_hex))
  140. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  141. cipher.hexverify(mac_hex)
  142. def test_message_chunks(self):
  143. # Validate that both associated data and plaintext/ciphertext
  144. # can be broken up in chunks of arbitrary length
  145. auth_data = get_tag_random("authenticated data", 127)
  146. plaintext = get_tag_random("plaintext", 127)
  147. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  148. cipher.update(auth_data)
  149. ciphertext, ref_mac = cipher.encrypt_and_digest(plaintext)
  150. def break_up(data, chunk_length):
  151. return [data[i:i+chunk_length] for i in range(0, len(data),
  152. chunk_length)]
  153. # Encryption
  154. for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:
  155. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  156. for chunk in break_up(auth_data, chunk_length):
  157. cipher.update(chunk)
  158. pt2 = b("")
  159. for chunk in break_up(ciphertext, chunk_length):
  160. pt2 += cipher.decrypt(chunk)
  161. pt2 += cipher.decrypt()
  162. self.assertEqual(plaintext, pt2)
  163. cipher.verify(ref_mac)
  164. # Decryption
  165. for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128:
  166. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  167. for chunk in break_up(auth_data, chunk_length):
  168. cipher.update(chunk)
  169. ct2 = b("")
  170. for chunk in break_up(plaintext, chunk_length):
  171. ct2 += cipher.encrypt(chunk)
  172. ct2 += cipher.encrypt()
  173. self.assertEqual(ciphertext, ct2)
  174. self.assertEqual(cipher.digest(), ref_mac)
  175. def test_bytearray(self):
  176. # Encrypt
  177. key_ba = bytearray(self.key_128)
  178. nonce_ba = bytearray(self.nonce_96)
  179. header_ba = bytearray(self.data)
  180. data_ba = bytearray(self.data)
  181. cipher1 = AES.new(self.key_128,
  182. AES.MODE_OCB,
  183. nonce=self.nonce_96)
  184. cipher1.update(self.data)
  185. ct = cipher1.encrypt(self.data) + cipher1.encrypt()
  186. tag = cipher1.digest()
  187. cipher2 = AES.new(key_ba,
  188. AES.MODE_OCB,
  189. nonce=nonce_ba)
  190. key_ba[:3] = b"\xFF\xFF\xFF"
  191. nonce_ba[:3] = b"\xFF\xFF\xFF"
  192. cipher2.update(header_ba)
  193. header_ba[:3] = b"\xFF\xFF\xFF"
  194. ct_test = cipher2.encrypt(data_ba) + cipher2.encrypt()
  195. data_ba[:3] = b"\xFF\xFF\xFF"
  196. tag_test = cipher2.digest()
  197. self.assertEqual(ct, ct_test)
  198. self.assertEqual(tag, tag_test)
  199. self.assertEqual(cipher1.nonce, cipher2.nonce)
  200. # Decrypt
  201. key_ba = bytearray(self.key_128)
  202. nonce_ba = bytearray(self.nonce_96)
  203. header_ba = bytearray(self.data)
  204. del data_ba
  205. cipher4 = AES.new(key_ba,
  206. AES.MODE_OCB,
  207. nonce=nonce_ba)
  208. key_ba[:3] = b"\xFF\xFF\xFF"
  209. nonce_ba[:3] = b"\xFF\xFF\xFF"
  210. cipher4.update(header_ba)
  211. header_ba[:3] = b"\xFF\xFF\xFF"
  212. pt_test = cipher4.decrypt_and_verify(bytearray(ct_test), bytearray(tag_test))
  213. self.assertEqual(self.data, pt_test)
  214. def test_memoryview(self):
  215. # Encrypt
  216. key_mv = memoryview(bytearray(self.key_128))
  217. nonce_mv = memoryview(bytearray(self.nonce_96))
  218. header_mv = memoryview(bytearray(self.data))
  219. data_mv = memoryview(bytearray(self.data))
  220. cipher1 = AES.new(self.key_128,
  221. AES.MODE_OCB,
  222. nonce=self.nonce_96)
  223. cipher1.update(self.data)
  224. ct = cipher1.encrypt(self.data) + cipher1.encrypt()
  225. tag = cipher1.digest()
  226. cipher2 = AES.new(key_mv,
  227. AES.MODE_OCB,
  228. nonce=nonce_mv)
  229. key_mv[:3] = b"\xFF\xFF\xFF"
  230. nonce_mv[:3] = b"\xFF\xFF\xFF"
  231. cipher2.update(header_mv)
  232. header_mv[:3] = b"\xFF\xFF\xFF"
  233. ct_test = cipher2.encrypt(data_mv) + cipher2.encrypt()
  234. data_mv[:3] = b"\xFF\xFF\xFF"
  235. tag_test = cipher2.digest()
  236. self.assertEqual(ct, ct_test)
  237. self.assertEqual(tag, tag_test)
  238. self.assertEqual(cipher1.nonce, cipher2.nonce)
  239. # Decrypt
  240. key_mv = memoryview(bytearray(self.key_128))
  241. nonce_mv = memoryview(bytearray(self.nonce_96))
  242. header_mv = memoryview(bytearray(self.data))
  243. del data_mv
  244. cipher4 = AES.new(key_mv,
  245. AES.MODE_OCB,
  246. nonce=nonce_mv)
  247. key_mv[:3] = b"\xFF\xFF\xFF"
  248. nonce_mv[:3] = b"\xFF\xFF\xFF"
  249. cipher4.update(header_mv)
  250. header_mv[:3] = b"\xFF\xFF\xFF"
  251. pt_test = cipher4.decrypt_and_verify(memoryview(ct_test), memoryview(tag_test))
  252. self.assertEqual(self.data, pt_test)
  253. class OcbFSMTests(unittest.TestCase):
  254. key_128 = get_tag_random("key_128", 16)
  255. nonce_96 = get_tag_random("nonce_128", 12)
  256. data = get_tag_random("data", 128)
  257. def test_valid_init_encrypt_decrypt_digest_verify(self):
  258. # No authenticated data, fixed plaintext
  259. # Verify path INIT->ENCRYPT->ENCRYPT(NONE)->DIGEST
  260. cipher = AES.new(self.key_128, AES.MODE_OCB,
  261. nonce=self.nonce_96)
  262. ct = cipher.encrypt(self.data)
  263. ct += cipher.encrypt()
  264. mac = cipher.digest()
  265. # Verify path INIT->DECRYPT->DECRYPT(NONCE)->VERIFY
  266. cipher = AES.new(self.key_128, AES.MODE_OCB,
  267. nonce=self.nonce_96)
  268. cipher.decrypt(ct)
  269. cipher.decrypt()
  270. cipher.verify(mac)
  271. def test_invalid_init_encrypt_decrypt_digest_verify(self):
  272. # No authenticated data, fixed plaintext
  273. # Verify path INIT->ENCRYPT->DIGEST
  274. cipher = AES.new(self.key_128, AES.MODE_OCB,
  275. nonce=self.nonce_96)
  276. ct = cipher.encrypt(self.data)
  277. self.assertRaises(TypeError, cipher.digest)
  278. # Verify path INIT->DECRYPT->VERIFY
  279. cipher = AES.new(self.key_128, AES.MODE_OCB,
  280. nonce=self.nonce_96)
  281. cipher.decrypt(ct)
  282. self.assertRaises(TypeError, cipher.verify)
  283. def test_valid_init_update_digest_verify(self):
  284. # No plaintext, fixed authenticated data
  285. # Verify path INIT->UPDATE->DIGEST
  286. cipher = AES.new(self.key_128, AES.MODE_OCB,
  287. nonce=self.nonce_96)
  288. cipher.update(self.data)
  289. mac = cipher.digest()
  290. # Verify path INIT->UPDATE->VERIFY
  291. cipher = AES.new(self.key_128, AES.MODE_OCB,
  292. nonce=self.nonce_96)
  293. cipher.update(self.data)
  294. cipher.verify(mac)
  295. def test_valid_full_path(self):
  296. # Fixed authenticated data, fixed plaintext
  297. # Verify path INIT->UPDATE->ENCRYPT->ENCRYPT(NONE)->DIGEST
  298. cipher = AES.new(self.key_128, AES.MODE_OCB,
  299. nonce=self.nonce_96)
  300. cipher.update(self.data)
  301. ct = cipher.encrypt(self.data)
  302. ct += cipher.encrypt()
  303. mac = cipher.digest()
  304. # Verify path INIT->UPDATE->DECRYPT->DECRYPT(NONE)->VERIFY
  305. cipher = AES.new(self.key_128, AES.MODE_OCB,
  306. nonce=self.nonce_96)
  307. cipher.update(self.data)
  308. cipher.decrypt(ct)
  309. cipher.decrypt()
  310. cipher.verify(mac)
  311. # Verify path INIT->UPDATE->ENCRYPT->ENCRYPT_AND_DIGEST
  312. cipher = AES.new(self.key_128, AES.MODE_OCB,
  313. nonce=self.nonce_96)
  314. cipher.update(self.data)
  315. ct1 = cipher.encrypt(self.data[:2])
  316. ct2, mac = cipher.encrypt_and_digest(self.data[2:])
  317. # Verify path INIT->UPDATE->DECRYPT->DECRYPT_AND_VERIFY
  318. cipher = AES.new(self.key_128, AES.MODE_OCB,
  319. nonce=self.nonce_96)
  320. cipher.update(self.data)
  321. cipher.decrypt(ct1)
  322. cipher.decrypt_and_verify(ct2, mac)
  323. def test_invalid_encrypt_after_final(self):
  324. cipher = AES.new(self.key_128, AES.MODE_OCB,
  325. nonce=self.nonce_96)
  326. cipher.update(self.data)
  327. cipher.encrypt(self.data)
  328. cipher.encrypt()
  329. self.assertRaises(TypeError, cipher.encrypt, self.data)
  330. def test_invalid_decrypt_after_final(self):
  331. cipher = AES.new(self.key_128, AES.MODE_OCB,
  332. nonce=self.nonce_96)
  333. cipher.update(self.data)
  334. cipher.decrypt(self.data)
  335. cipher.decrypt()
  336. self.assertRaises(TypeError, cipher.decrypt, self.data)
  337. def test_valid_init_digest(self):
  338. # Verify path INIT->DIGEST
  339. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  340. cipher.digest()
  341. def test_valid_init_verify(self):
  342. # Verify path INIT->VERIFY
  343. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  344. mac = cipher.digest()
  345. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  346. cipher.verify(mac)
  347. def test_valid_multiple_encrypt_or_decrypt(self):
  348. for method_name in "encrypt", "decrypt":
  349. for auth_data in (None, b("333"), self.data,
  350. self.data + b("3")):
  351. cipher = AES.new(self.key_128, AES.MODE_OCB,
  352. nonce=self.nonce_96)
  353. if auth_data is not None:
  354. cipher.update(auth_data)
  355. method = getattr(cipher, method_name)
  356. method(self.data)
  357. method(self.data)
  358. method(self.data)
  359. method(self.data)
  360. method()
  361. def test_valid_multiple_digest_or_verify(self):
  362. # Multiple calls to digest
  363. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  364. cipher.update(self.data)
  365. first_mac = cipher.digest()
  366. for x in range(4):
  367. self.assertEqual(first_mac, cipher.digest())
  368. # Multiple calls to verify
  369. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  370. cipher.update(self.data)
  371. for x in range(5):
  372. cipher.verify(first_mac)
  373. def test_valid_encrypt_and_digest_decrypt_and_verify(self):
  374. # encrypt_and_digest
  375. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  376. cipher.update(self.data)
  377. ct, mac = cipher.encrypt_and_digest(self.data)
  378. # decrypt_and_verify
  379. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  380. cipher.update(self.data)
  381. pt = cipher.decrypt_and_verify(ct, mac)
  382. self.assertEqual(self.data, pt)
  383. def test_invalid_mixing_encrypt_decrypt(self):
  384. # Once per method, with or without assoc. data
  385. for method1_name, method2_name in (("encrypt", "decrypt"),
  386. ("decrypt", "encrypt")):
  387. for assoc_data_present in (True, False):
  388. cipher = AES.new(self.key_128, AES.MODE_OCB,
  389. nonce=self.nonce_96)
  390. if assoc_data_present:
  391. cipher.update(self.data)
  392. getattr(cipher, method1_name)(self.data)
  393. self.assertRaises(TypeError, getattr(cipher, method2_name),
  394. self.data)
  395. def test_invalid_encrypt_or_update_after_digest(self):
  396. for method_name in "encrypt", "update":
  397. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  398. cipher.encrypt(self.data)
  399. cipher.encrypt()
  400. cipher.digest()
  401. self.assertRaises(TypeError, getattr(cipher, method_name),
  402. self.data)
  403. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  404. cipher.encrypt_and_digest(self.data)
  405. def test_invalid_decrypt_or_update_after_verify(self):
  406. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  407. ct = cipher.encrypt(self.data)
  408. ct += cipher.encrypt()
  409. mac = cipher.digest()
  410. for method_name in "decrypt", "update":
  411. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  412. cipher.decrypt(ct)
  413. cipher.decrypt()
  414. cipher.verify(mac)
  415. self.assertRaises(TypeError, getattr(cipher, method_name),
  416. self.data)
  417. cipher = AES.new(self.key_128, AES.MODE_OCB, nonce=self.nonce_96)
  418. cipher.decrypt_and_verify(ct, mac)
  419. self.assertRaises(TypeError, getattr(cipher, method_name),
  420. self.data)
  421. def algo_rfc7253(keylen, taglen, noncelen):
  422. """Implement the algorithm at page 18 of RFC 7253"""
  423. key = bchr(0) * (keylen // 8 - 1) + bchr(taglen)
  424. C = b""
  425. for i in range(128):
  426. S = bchr(0) * i
  427. N = long_to_bytes(3 * i + 1, noncelen // 8)
  428. cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
  429. cipher.update(S)
  430. C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest()
  431. N = long_to_bytes(3 * i + 2, noncelen // 8)
  432. cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
  433. C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest()
  434. N = long_to_bytes(3 * i + 3, noncelen // 8)
  435. cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
  436. cipher.update(S)
  437. C += cipher.encrypt() + cipher.digest()
  438. N = long_to_bytes(385, noncelen // 8)
  439. cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8)
  440. cipher.update(C)
  441. return cipher.encrypt() + cipher.digest()
  442. class OcbRfc7253Test(unittest.TestCase):
  443. # Tuple with
  444. # - nonce
  445. # - authenticated data
  446. # - plaintext
  447. # - ciphertext and 16 byte MAC tag
  448. tv1_key = "000102030405060708090A0B0C0D0E0F"
  449. tv1 = (
  450. (
  451. "BBAA99887766554433221100",
  452. "",
  453. "",
  454. "785407BFFFC8AD9EDCC5520AC9111EE6"
  455. ),
  456. (
  457. "BBAA99887766554433221101",
  458. "0001020304050607",
  459. "0001020304050607",
  460. "6820B3657B6F615A5725BDA0D3B4EB3A257C9AF1F8F03009"
  461. ),
  462. (
  463. "BBAA99887766554433221102",
  464. "0001020304050607",
  465. "",
  466. "81017F8203F081277152FADE694A0A00"
  467. ),
  468. (
  469. "BBAA99887766554433221103",
  470. "",
  471. "0001020304050607",
  472. "45DD69F8F5AAE72414054CD1F35D82760B2CD00D2F99BFA9"
  473. ),
  474. (
  475. "BBAA99887766554433221104",
  476. "000102030405060708090A0B0C0D0E0F",
  477. "000102030405060708090A0B0C0D0E0F",
  478. "571D535B60B277188BE5147170A9A22C3AD7A4FF3835B8C5"
  479. "701C1CCEC8FC3358"
  480. ),
  481. (
  482. "BBAA99887766554433221105",
  483. "000102030405060708090A0B0C0D0E0F",
  484. "",
  485. "8CF761B6902EF764462AD86498CA6B97"
  486. ),
  487. (
  488. "BBAA99887766554433221106",
  489. "",
  490. "000102030405060708090A0B0C0D0E0F",
  491. "5CE88EC2E0692706A915C00AEB8B2396F40E1C743F52436B"
  492. "DF06D8FA1ECA343D"
  493. ),
  494. (
  495. "BBAA99887766554433221107",
  496. "000102030405060708090A0B0C0D0E0F1011121314151617",
  497. "000102030405060708090A0B0C0D0E0F1011121314151617",
  498. "1CA2207308C87C010756104D8840CE1952F09673A448A122"
  499. "C92C62241051F57356D7F3C90BB0E07F"
  500. ),
  501. (
  502. "BBAA99887766554433221108",
  503. "000102030405060708090A0B0C0D0E0F1011121314151617",
  504. "",
  505. "6DC225A071FC1B9F7C69F93B0F1E10DE"
  506. ),
  507. (
  508. "BBAA99887766554433221109",
  509. "",
  510. "000102030405060708090A0B0C0D0E0F1011121314151617",
  511. "221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3C"
  512. "E725F32494B9F914D85C0B1EB38357FF"
  513. ),
  514. (
  515. "BBAA9988776655443322110A",
  516. "000102030405060708090A0B0C0D0E0F1011121314151617"
  517. "18191A1B1C1D1E1F",
  518. "000102030405060708090A0B0C0D0E0F1011121314151617"
  519. "18191A1B1C1D1E1F",
  520. "BD6F6C496201C69296C11EFD138A467ABD3C707924B964DE"
  521. "AFFC40319AF5A48540FBBA186C5553C68AD9F592A79A4240"
  522. ),
  523. (
  524. "BBAA9988776655443322110B",
  525. "000102030405060708090A0B0C0D0E0F1011121314151617"
  526. "18191A1B1C1D1E1F",
  527. "",
  528. "FE80690BEE8A485D11F32965BC9D2A32"
  529. ),
  530. (
  531. "BBAA9988776655443322110C",
  532. "",
  533. "000102030405060708090A0B0C0D0E0F1011121314151617"
  534. "18191A1B1C1D1E1F",
  535. "2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF4"
  536. "6040C53F1432BCDFB5E1DDE3BC18A5F840B52E653444D5DF"
  537. ),
  538. (
  539. "BBAA9988776655443322110D",
  540. "000102030405060708090A0B0C0D0E0F1011121314151617"
  541. "18191A1B1C1D1E1F2021222324252627",
  542. "000102030405060708090A0B0C0D0E0F1011121314151617"
  543. "18191A1B1C1D1E1F2021222324252627",
  544. "D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460"
  545. "6E59F9C1D0DDC54B65E8628E568BAD7AED07BA06A4A69483"
  546. "A7035490C5769E60"
  547. ),
  548. (
  549. "BBAA9988776655443322110E",
  550. "000102030405060708090A0B0C0D0E0F1011121314151617"
  551. "18191A1B1C1D1E1F2021222324252627",
  552. "",
  553. "C5CD9D1850C141E358649994EE701B68"
  554. ),
  555. (
  556. "BBAA9988776655443322110F",
  557. "",
  558. "000102030405060708090A0B0C0D0E0F1011121314151617"
  559. "18191A1B1C1D1E1F2021222324252627",
  560. "4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15"
  561. "A5DDBFC5787E50B5CC55EE507BCB084E479AD363AC366B95"
  562. "A98CA5F3000B1479"
  563. )
  564. )
  565. # Tuple with
  566. # - key
  567. # - nonce
  568. # - authenticated data
  569. # - plaintext
  570. # - ciphertext and 12 byte MAC tag
  571. tv2 = (
  572. "0F0E0D0C0B0A09080706050403020100",
  573. "BBAA9988776655443322110D",
  574. "000102030405060708090A0B0C0D0E0F1011121314151617"
  575. "18191A1B1C1D1E1F2021222324252627",
  576. "000102030405060708090A0B0C0D0E0F1011121314151617"
  577. "18191A1B1C1D1E1F2021222324252627",
  578. "1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1"
  579. "A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FD"
  580. "AC4F02AA"
  581. )
  582. # Tuple with
  583. # - key length
  584. # - MAC tag length
  585. # - Expected output
  586. tv3 = (
  587. (128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2"),
  588. (192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17"),
  589. (256, 128, "D90EB8E9C977C88B79DD793D7FFA161C"),
  590. (128, 96, "77A3D8E73589158D25D01209"),
  591. (192, 96, "05D56EAD2752C86BE6932C5E"),
  592. (256, 96, "5458359AC23B0CBA9E6330DD"),
  593. (128, 64, "192C9B7BD90BA06A"),
  594. (192, 64, "0066BC6E0EF34E24"),
  595. (256, 64, "7D4EA5D445501CBE"),
  596. )
  597. def test1(self):
  598. key = unhexlify(b(self.tv1_key))
  599. for tv in self.tv1:
  600. nonce, aad, pt, ct = [unhexlify(b(x)) for x in tv]
  601. ct, mac_tag = ct[:-16], ct[-16:]
  602. cipher = AES.new(key, AES.MODE_OCB, nonce=nonce)
  603. cipher.update(aad)
  604. ct2 = cipher.encrypt(pt) + cipher.encrypt()
  605. self.assertEqual(ct, ct2)
  606. self.assertEqual(mac_tag, cipher.digest())
  607. cipher = AES.new(key, AES.MODE_OCB, nonce=nonce)
  608. cipher.update(aad)
  609. pt2 = cipher.decrypt(ct) + cipher.decrypt()
  610. self.assertEqual(pt, pt2)
  611. cipher.verify(mac_tag)
  612. def test2(self):
  613. key, nonce, aad, pt, ct = [unhexlify(b(x)) for x in self.tv2]
  614. ct, mac_tag = ct[:-12], ct[-12:]
  615. cipher = AES.new(key, AES.MODE_OCB, nonce=nonce, mac_len=12)
  616. cipher.update(aad)
  617. ct2 = cipher.encrypt(pt) + cipher.encrypt()
  618. self.assertEqual(ct, ct2)
  619. self.assertEqual(mac_tag, cipher.digest())
  620. cipher = AES.new(key, AES.MODE_OCB, nonce=nonce, mac_len=12)
  621. cipher.update(aad)
  622. pt2 = cipher.decrypt(ct) + cipher.decrypt()
  623. self.assertEqual(pt, pt2)
  624. cipher.verify(mac_tag)
  625. def test3(self):
  626. for keylen, taglen, result in self.tv3:
  627. result2 = algo_rfc7253(keylen, taglen, 96)
  628. self.assertEqual(unhexlify(b(result)), result2)
  629. class OcbDkgTest(unittest.TestCase):
  630. """Test vectors from https://gitlab.com/dkg/ocb-test-vectors"""
  631. def test_1_2(self):
  632. tvs = []
  633. for fi in (1, 2):
  634. for nb in (104, 112, 120):
  635. tv_file = load_test_vectors(("Cipher", "AES"),
  636. "test-vector-%d-nonce%d.txt" % (fi, nb),
  637. "DKG tests, %d, %d bits" % (fi, nb),
  638. {})
  639. if tv_file is None:
  640. break
  641. key = tv_file[0].k
  642. for tv in tv_file[1:]:
  643. tv.k = key
  644. tvs.append(tv)
  645. for tv in tvs:
  646. k, n, a, p, c = tv.k, tv.n, tv.a, tv.p, tv.c
  647. mac_len = len(c) - len(p)
  648. cipher = AES.new(k, AES.MODE_OCB, nonce=n, mac_len=mac_len)
  649. cipher.update(a)
  650. c_out, tag_out = cipher.encrypt_and_digest(p)
  651. self.assertEqual(c, c_out + tag_out)
  652. def test_3(self):
  653. def check(keylen, taglen, noncelen, exp):
  654. result = algo_rfc7253(keylen, taglen, noncelen)
  655. self.assertEqual(result, unhexlify(exp))
  656. # test-vector-3-nonce104.txt
  657. check(128, 128, 104, "C47F5F0341E15326D4D1C46F47F05062")
  658. check(192, 128, 104, "95B9167A38EB80495DFC561A8486E109")
  659. check(256, 128, 104, "AFE1CDDB97028FD92F8FB3C8CFBA7D83")
  660. check(128, 96, 104, "F471B4983BA80946DF217A54")
  661. check(192, 96, 104, "5AE828BC51C24D85FA5CC7B2")
  662. check(256, 96, 104, "8C8335982E2B734616CAD14C")
  663. check(128, 64, 104, "B553F74B85FD1E5B")
  664. check(192, 64, 104, "3B49D20E513531F9")
  665. check(256, 64, 104, "ED6DA5B1216BF8BB")
  666. # test-vector-3-nonce112.txt
  667. check(128, 128, 112, "CA8AFCA031BAC3F480A583BD6C50A547")
  668. check(192, 128, 112, "D170C1DF356308079DA9A3F619147148")
  669. check(256, 128, 112, "57F94381F2F9231EFB04AECD323757C3")
  670. check(128, 96, 112, "3A618B2531ED39F260C750DC")
  671. check(192, 96, 112, "9071EB89FEDBADDA88FD286E")
  672. check(256, 96, 112, "FDF0EFB97F21A39AC4BAB5AC")
  673. check(128, 64, 112, "FAB2FF3A8DD82A13")
  674. check(192, 64, 112, "AC01D912BD0737D3")
  675. check(256, 64, 112, "9D1FD0B500EA4ECF")
  676. # test-vector-3-nonce120.txt
  677. check(128, 128, 120, "9E043A7140A25FB91F43BCC9DD7E0F46")
  678. check(192, 128, 120, "680000E53908323A7F396B955B8EC641")
  679. check(256, 128, 120, "8304B97FAACDA56E676602E1878A7E6F")
  680. check(128, 96, 120, "81F978AC9867E825D339847D")
  681. check(192, 96, 120, "EFCF2D60B24926ADA48CF5B1")
  682. check(256, 96, 120, "84961DC56E917B165E58C174")
  683. check(128, 64, 120, "227AEE6C9D905A61")
  684. check(192, 64, 120, "541DE691B9E1A2F9")
  685. check(256, 64, 120, "B0E761381C7129FC")
  686. def test_2_bugfix(self):
  687. nonce = unhexlify("EEDDCCBBAA9988776655443322110D")
  688. key = unhexlify("0F0E0D0C0B0A09080706050403020100")
  689. A = unhexlify("000102030405060708090A0B0C0D0E0F1011121314151617"
  690. "18191A1B1C1D1E1F2021222324252627")
  691. P = unhexlify("000102030405060708090A0B0C0D0E0F1011121314151617"
  692. "18191A1B1C1D1E1F2021222324252627")
  693. C = unhexlify("07E903BFC49552411ABC865F5ECE60F6FAD1F5A9F14D3070"
  694. "FA2F1308A563207FFE14C1EEA44B22059C7484319D8A2C53"
  695. "C236A7B3")
  696. mac_len = len(C) - len(P)
  697. # Prior to version 3.17, a nonce of maximum length (15 bytes)
  698. # was actually used as a 14 byte nonce. The last byte was erroneously
  699. # ignored.
  700. buggy_result = unhexlify("BA015C4E5AE54D76C890AE81BD40DC57"
  701. "03EDC30E8AC2A58BC5D8FA4D61C5BAE6"
  702. "C39BEAC435B2FD56A2A5085C1B135D77"
  703. "0C8264B7")
  704. cipher = AES.new(key, AES.MODE_OCB, nonce=nonce[:-1], mac_len=mac_len)
  705. cipher.update(A)
  706. C_out2, tag_out2 = cipher.encrypt_and_digest(P)
  707. self.assertEqual(buggy_result, C_out2 + tag_out2)
  708. def get_tests(config={}):
  709. tests = []
  710. tests += list_test_cases(OcbTests)
  711. tests += list_test_cases(OcbFSMTests)
  712. tests += list_test_cases(OcbRfc7253Test)
  713. tests += list_test_cases(OcbDkgTest)
  714. return tests
  715. if __name__ == '__main__':
  716. def suite():
  717. return unittest.TestSuite(get_tests())
  718. unittest.main(defaultTest='suite')