test_KDF.py 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. # -*- coding: utf-8 -*-
  2. #
  3. # SelfTest/Protocol/test_KDF.py: Self-test for key derivation functions
  4. #
  5. # ===================================================================
  6. # The contents of this file are dedicated to the public domain. To
  7. # the extent that dedication to the public domain is not available,
  8. # everyone is granted a worldwide, perpetual, royalty-free,
  9. # non-exclusive license to exercise all rights associated with the
  10. # contents of this file for any purpose whatsoever.
  11. # No rights are reserved.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. # SOFTWARE.
  21. # ===================================================================
  22. import re
  23. import unittest
  24. from binascii import unhexlify
  25. from Crypto.Util.py3compat import b, bchr
  26. from Crypto.SelfTest.st_common import list_test_cases
  27. from Crypto.SelfTest.loader import load_test_vectors, load_test_vectors_wycheproof
  28. from Crypto.Hash import SHA1, HMAC, SHA256, MD5, SHA224, SHA384, SHA512
  29. from Crypto.Cipher import AES, DES3
  30. from Crypto.Protocol.KDF import (PBKDF1, PBKDF2, _S2V, HKDF, scrypt,
  31. bcrypt, bcrypt_check,
  32. SP800_108_Counter)
  33. from Crypto.Protocol.KDF import _bcrypt_decode
  34. def t2b(t):
  35. if t is None:
  36. return None
  37. t2 = t.replace(" ", "").replace("\n", "")
  38. return unhexlify(b(t2))
  39. class TestVector(object):
  40. pass
  41. class PBKDF1_Tests(unittest.TestCase):
  42. # List of tuples with test data.
  43. # Each tuple is made up by:
  44. # Item #0: a pass phrase
  45. # Item #1: salt (8 bytes encoded in hex)
  46. # Item #2: output key length
  47. # Item #3: iterations to use
  48. # Item #4: expected result (encoded in hex)
  49. _testData = (
  50. # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
  51. ("password", "78578E5A5D63CB06", 16, 1000, "DC19847E05C64D2FAF10EBFB4A3D2A20"),
  52. )
  53. def test1(self):
  54. v = self._testData[0]
  55. res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1)
  56. self.assertEqual(res, t2b(v[4]))
  57. class PBKDF2_Tests(unittest.TestCase):
  58. # List of tuples with test data.
  59. # Each tuple is made up by:
  60. # Item #0: a pass phrase
  61. # Item #1: salt (encoded in hex)
  62. # Item #2: output key length
  63. # Item #3: iterations to use
  64. # Item #4: hash module
  65. # Item #5: expected result (encoded in hex)
  66. _testData = (
  67. # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
  68. ("password","78578E5A5D63CB06",24,2048, SHA1, "BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"),
  69. # From RFC 6050
  70. ("password","73616c74", 20, 1, SHA1, "0c60c80f961f0e71f3a9b524af6012062fe037a6"),
  71. ("password","73616c74", 20, 2, SHA1, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"),
  72. ("password","73616c74", 20, 4096, SHA1, "4b007901b765489abead49d926f721d065a429c1"),
  73. ("passwordPASSWORDpassword","73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74",
  74. 25, 4096, SHA1, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"),
  75. ( 'pass\x00word',"7361006c74",16,4096, SHA1, "56fa6aa75548099dcc37d7f03425e0c3"),
  76. # From draft-josefsson-scrypt-kdf-01, Chapter 10
  77. ( 'passwd', '73616c74', 64, 1, SHA256, "55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783"),
  78. ( 'Password', '4e61436c', 64, 80000, SHA256, "4ddcd8f60b98be21830cee5ef22701f9641a4418d04c0414aeff08876b34ab56a1d425a1225833549adb841b51c9b3176a272bdebba1d078478f62b397f33c8d"),
  79. )
  80. def test1(self):
  81. # Test only for HMAC-SHA1 as PRF
  82. def prf_SHA1(p,s):
  83. return HMAC.new(p,s,SHA1).digest()
  84. def prf_SHA256(p,s):
  85. return HMAC.new(p,s,SHA256).digest()
  86. for i, v in enumerate(self._testData):
  87. password = v[0]
  88. salt = t2b(v[1])
  89. out_len = v[2]
  90. iters = v[3]
  91. hash_mod = v[4]
  92. expected = t2b(v[5])
  93. if hash_mod is SHA1:
  94. res = PBKDF2(password, salt, out_len, iters)
  95. self.assertEqual(res, expected)
  96. res = PBKDF2(password, salt, out_len, iters, prf_SHA1)
  97. self.assertEqual(res, expected)
  98. else:
  99. res = PBKDF2(password, salt, out_len, iters, prf_SHA256)
  100. self.assertEqual(res, expected)
  101. def test2(self):
  102. # Verify that prf and hmac_hash_module are mutual exclusive
  103. def prf_SHA1(p,s):
  104. return HMAC.new(p,s,SHA1).digest()
  105. self.assertRaises(ValueError, PBKDF2, b("xxx"), b("yyy"), 16, 100,
  106. prf=prf_SHA1, hmac_hash_module=SHA1)
  107. def test3(self):
  108. # Verify that hmac_hash_module works like prf
  109. password = b("xxx")
  110. salt = b("yyy")
  111. for hashmod in (MD5, SHA1, SHA224, SHA256, SHA384, SHA512):
  112. pr1 = PBKDF2(password, salt, 16, 100,
  113. prf=lambda p, s: HMAC.new(p,s,hashmod).digest())
  114. pr2 = PBKDF2(password, salt, 16, 100, hmac_hash_module=hashmod)
  115. self.assertEqual(pr1, pr2)
  116. def test4(self):
  117. # Verify that PBKDF2 can take bytes or strings as password or salt
  118. k1 = PBKDF2("xxx", b("yyy"), 16, 10)
  119. k2 = PBKDF2(b("xxx"), b("yyy"), 16, 10)
  120. self.assertEqual(k1, k2)
  121. k1 = PBKDF2(b("xxx"), "yyy", 16, 10)
  122. k2 = PBKDF2(b("xxx"), b("yyy"), 16, 10)
  123. self.assertEqual(k1, k2)
  124. class S2V_Tests(unittest.TestCase):
  125. # Sequence of test vectors.
  126. # Each test vector is made up by:
  127. # Item #0: a tuple of strings
  128. # Item #1: an AES key
  129. # Item #2: the result
  130. # Item #3: the cipher module S2V is based on
  131. # Everything is hex encoded
  132. _testData = [
  133. # RFC5297, A.1
  134. (
  135. ( '101112131415161718191a1b1c1d1e1f2021222324252627',
  136. '112233445566778899aabbccddee' ),
  137. 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0',
  138. '85632d07c6e8f37f950acd320a2ecc93',
  139. AES
  140. ),
  141. # RFC5297, A.2
  142. (
  143. ( '00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddcc'+
  144. 'bbaa99887766554433221100',
  145. '102030405060708090a0',
  146. '09f911029d74e35bd84156c5635688c0',
  147. '7468697320697320736f6d6520706c61'+
  148. '696e7465787420746f20656e63727970'+
  149. '74207573696e67205349562d414553'),
  150. '7f7e7d7c7b7a79787776757473727170',
  151. '7bdb6e3b432667eb06f4d14bff2fbd0f',
  152. AES
  153. ),
  154. ]
  155. def test1(self):
  156. """Verify correctness of test vector"""
  157. for tv in self._testData:
  158. s2v = _S2V.new(t2b(tv[1]), tv[3])
  159. for s in tv[0]:
  160. s2v.update(t2b(s))
  161. result = s2v.derive()
  162. self.assertEqual(result, t2b(tv[2]))
  163. def test2(self):
  164. """Verify that no more than 127(AES) and 63(TDES)
  165. components are accepted."""
  166. key = bchr(0) * 8 + bchr(255) * 8
  167. for module in (AES, DES3):
  168. s2v = _S2V.new(key, module)
  169. max_comps = module.block_size*8-1
  170. for i in range(max_comps):
  171. s2v.update(b("XX"))
  172. self.assertRaises(TypeError, s2v.update, b("YY"))
  173. class HKDF_Tests(unittest.TestCase):
  174. # Test vectors from RFC5869, Appendix A
  175. # Each tuple is made up by:
  176. # Item #0: hash module
  177. # Item #1: secret
  178. # Item #2: salt
  179. # Item #3: context
  180. # Item #4: expected result
  181. _test_vector = (
  182. (
  183. SHA256,
  184. "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
  185. "000102030405060708090a0b0c",
  186. "f0f1f2f3f4f5f6f7f8f9",
  187. 42,
  188. "3cb25f25faacd57a90434f64d0362f2a" +
  189. "2d2d0a90cf1a5a4c5db02d56ecc4c5bf" +
  190. "34007208d5b887185865"
  191. ),
  192. (
  193. SHA256,
  194. "000102030405060708090a0b0c0d0e0f" +
  195. "101112131415161718191a1b1c1d1e1f" +
  196. "202122232425262728292a2b2c2d2e2f" +
  197. "303132333435363738393a3b3c3d3e3f" +
  198. "404142434445464748494a4b4c4d4e4f",
  199. "606162636465666768696a6b6c6d6e6f" +
  200. "707172737475767778797a7b7c7d7e7f" +
  201. "808182838485868788898a8b8c8d8e8f" +
  202. "909192939495969798999a9b9c9d9e9f" +
  203. "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
  204. "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" +
  205. "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" +
  206. "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" +
  207. "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" +
  208. "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
  209. 82,
  210. "b11e398dc80327a1c8e7f78c596a4934" +
  211. "4f012eda2d4efad8a050cc4c19afa97c" +
  212. "59045a99cac7827271cb41c65e590e09" +
  213. "da3275600c2f09b8367793a9aca3db71" +
  214. "cc30c58179ec3e87c14c01d5c1f3434f" +
  215. "1d87"
  216. ),
  217. (
  218. SHA256,
  219. "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
  220. None,
  221. None,
  222. 42,
  223. "8da4e775a563c18f715f802a063c5a31" +
  224. "b8a11f5c5ee1879ec3454e5f3c738d2d" +
  225. "9d201395faa4b61a96c8"
  226. ),
  227. (
  228. SHA1,
  229. "0b0b0b0b0b0b0b0b0b0b0b",
  230. "000102030405060708090a0b0c",
  231. "f0f1f2f3f4f5f6f7f8f9",
  232. 42,
  233. "085a01ea1b10f36933068b56efa5ad81" +
  234. "a4f14b822f5b091568a9cdd4f155fda2" +
  235. "c22e422478d305f3f896"
  236. ),
  237. (
  238. SHA1,
  239. "000102030405060708090a0b0c0d0e0f" +
  240. "101112131415161718191a1b1c1d1e1f" +
  241. "202122232425262728292a2b2c2d2e2f" +
  242. "303132333435363738393a3b3c3d3e3f" +
  243. "404142434445464748494a4b4c4d4e4f",
  244. "606162636465666768696a6b6c6d6e6f" +
  245. "707172737475767778797a7b7c7d7e7f" +
  246. "808182838485868788898a8b8c8d8e8f" +
  247. "909192939495969798999a9b9c9d9e9f" +
  248. "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
  249. "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" +
  250. "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" +
  251. "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" +
  252. "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" +
  253. "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
  254. 82,
  255. "0bd770a74d1160f7c9f12cd5912a06eb" +
  256. "ff6adcae899d92191fe4305673ba2ffe" +
  257. "8fa3f1a4e5ad79f3f334b3b202b2173c" +
  258. "486ea37ce3d397ed034c7f9dfeb15c5e" +
  259. "927336d0441f4c4300e2cff0d0900b52" +
  260. "d3b4"
  261. ),
  262. (
  263. SHA1,
  264. "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
  265. "",
  266. "",
  267. 42,
  268. "0ac1af7002b3d761d1e55298da9d0506" +
  269. "b9ae52057220a306e07b6b87e8df21d0" +
  270. "ea00033de03984d34918"
  271. ),
  272. (
  273. SHA1,
  274. "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c",
  275. None,
  276. "",
  277. 42,
  278. "2c91117204d745f3500d636a62f64f0a" +
  279. "b3bae548aa53d423b0d1f27ebba6f5e5" +
  280. "673a081d70cce7acfc48"
  281. )
  282. )
  283. def test1(self):
  284. for tv in self._test_vector:
  285. secret, salt, info, exp = [ t2b(tv[x]) for x in (1,2,3,5) ]
  286. key_len, hashmod = [ tv[x] for x in (4,0) ]
  287. output = HKDF(secret, key_len, salt, hashmod, 1, info)
  288. self.assertEqual(output, exp)
  289. def test2(self):
  290. ref = HKDF(b("XXXXXX"), 12, b("YYYY"), SHA1)
  291. # Same output, but this time split over 2 keys
  292. key1, key2 = HKDF(b("XXXXXX"), 6, b("YYYY"), SHA1, 2)
  293. self.assertEqual((ref[:6], ref[6:]), (key1, key2))
  294. # Same output, but this time split over 3 keys
  295. key1, key2, key3 = HKDF(b("XXXXXX"), 4, b("YYYY"), SHA1, 3)
  296. self.assertEqual((ref[:4], ref[4:8], ref[8:]), (key1, key2, key3))
  297. class scrypt_Tests(unittest.TestCase):
  298. # Test vectors taken from
  299. # https://tools.ietf.org/html/rfc7914
  300. # - password
  301. # - salt
  302. # - N
  303. # - r
  304. # - p
  305. data = (
  306. (
  307. "",
  308. "",
  309. 16, # 2K
  310. 1,
  311. 1,
  312. """
  313. 77 d6 57 62 38 65 7b 20 3b 19 ca 42 c1 8a 04 97
  314. f1 6b 48 44 e3 07 4a e8 df df fa 3f ed e2 14 42
  315. fc d0 06 9d ed 09 48 f8 32 6a 75 3a 0f c8 1f 17
  316. e8 d3 e0 fb 2e 0d 36 28 cf 35 e2 0c 38 d1 89 06
  317. """
  318. ),
  319. (
  320. "password",
  321. "NaCl",
  322. 1024, # 1M
  323. 8,
  324. 16,
  325. """
  326. fd ba be 1c 9d 34 72 00 78 56 e7 19 0d 01 e9 fe
  327. 7c 6a d7 cb c8 23 78 30 e7 73 76 63 4b 37 31 62
  328. 2e af 30 d9 2e 22 a3 88 6f f1 09 27 9d 98 30 da
  329. c7 27 af b9 4a 83 ee 6d 83 60 cb df a2 cc 06 40
  330. """
  331. ),
  332. (
  333. "pleaseletmein",
  334. "SodiumChloride",
  335. 16384, # 16M
  336. 8,
  337. 1,
  338. """
  339. 70 23 bd cb 3a fd 73 48 46 1c 06 cd 81 fd 38 eb
  340. fd a8 fb ba 90 4f 8e 3e a9 b5 43 f6 54 5d a1 f2
  341. d5 43 29 55 61 3f 0f cf 62 d4 97 05 24 2a 9a f9
  342. e6 1e 85 dc 0d 65 1e 40 df cf 01 7b 45 57 58 87
  343. """
  344. ),
  345. (
  346. "pleaseletmein",
  347. "SodiumChloride",
  348. 1048576, # 1G
  349. 8,
  350. 1,
  351. """
  352. 21 01 cb 9b 6a 51 1a ae ad db be 09 cf 70 f8 81
  353. ec 56 8d 57 4a 2f fd 4d ab e5 ee 98 20 ad aa 47
  354. 8e 56 fd 8f 4b a5 d0 9f fa 1c 6d 92 7c 40 f4 c3
  355. 37 30 40 49 e8 a9 52 fb cb f4 5c 6f a7 7a 41 a4
  356. """
  357. ),
  358. )
  359. def setUp(self):
  360. new_test_vectors = []
  361. for tv in self.data:
  362. new_tv = TestVector()
  363. new_tv.P = b(tv[0])
  364. new_tv.S = b(tv[1])
  365. new_tv.N = tv[2]
  366. new_tv.r = tv[3]
  367. new_tv.p = tv[4]
  368. new_tv.output = t2b(tv[5])
  369. new_tv.dkLen = len(new_tv.output)
  370. new_test_vectors.append(new_tv)
  371. self.data = new_test_vectors
  372. def test2(self):
  373. for tv in self.data:
  374. try:
  375. output = scrypt(tv.P, tv.S, tv.dkLen, tv.N, tv.r, tv.p)
  376. except ValueError as e:
  377. if " 2 " in str(e) and tv.N >= 1048576:
  378. import warnings
  379. warnings.warn("Not enough memory to unit test scrypt() with N=1048576", RuntimeWarning)
  380. continue
  381. else:
  382. raise e
  383. self.assertEqual(output, tv.output)
  384. def test3(self):
  385. ref = scrypt(b("password"), b("salt"), 12, 16, 1, 1)
  386. # Same output, but this time split over 2 keys
  387. key1, key2 = scrypt(b("password"), b("salt"), 6, 16, 1, 1, 2)
  388. self.assertEqual((ref[:6], ref[6:]), (key1, key2))
  389. # Same output, but this time split over 3 keys
  390. key1, key2, key3 = scrypt(b("password"), b("salt"), 4, 16, 1, 1, 3)
  391. self.assertEqual((ref[:4], ref[4:8], ref[8:]), (key1, key2, key3))
  392. class bcrypt_Tests(unittest.TestCase):
  393. def test_negative_cases(self):
  394. self.assertRaises(ValueError, bcrypt, b"1" * 73, 10)
  395. self.assertRaises(ValueError, bcrypt, b"1" * 10, 3)
  396. self.assertRaises(ValueError, bcrypt, b"1" * 10, 32)
  397. self.assertRaises(ValueError, bcrypt, b"1" * 10, 4, salt=b"")
  398. self.assertRaises(ValueError, bcrypt, b"1" * 10, 4, salt=b"1")
  399. self.assertRaises(ValueError, bcrypt, b"1" * 10, 4, salt=b"1" * 17)
  400. self.assertRaises(ValueError, bcrypt, b"1\x00" * 10, 4)
  401. def test_bytearray_mismatch(self):
  402. ref = bcrypt("pwd", 4)
  403. bcrypt_check("pwd", ref)
  404. bref = bytearray(ref)
  405. bcrypt_check("pwd", bref)
  406. wrong = ref[:-1] + bchr(bref[-1] ^ 0x01)
  407. self.assertRaises(ValueError, bcrypt_check, "pwd", wrong)
  408. wrong = b"x" + ref[1:]
  409. self.assertRaises(ValueError, bcrypt_check, "pwd", wrong)
  410. # https://github.com/patrickfav/bcrypt/wiki/Published-Test-Vectors
  411. def test_empty_password(self):
  412. # password, cost, salt, bcrypt hash
  413. tvs = [
  414. (b"", 4, b"zVHmKQtGGQob.b/Nc7l9NO", b"$2a$04$zVHmKQtGGQob.b/Nc7l9NO8UlrYcW05FiuCj/SxsFO/ZtiN9.mNzy"),
  415. (b"", 5, b"zVHmKQtGGQob.b/Nc7l9NO", b"$2a$05$zVHmKQtGGQob.b/Nc7l9NOWES.1hkVBgy5IWImh9DOjKNU8atY4Iy"),
  416. (b"", 6, b"zVHmKQtGGQob.b/Nc7l9NO", b"$2a$06$zVHmKQtGGQob.b/Nc7l9NOjOl7l4oz3WSh5fJ6414Uw8IXRAUoiaO"),
  417. (b"", 7, b"zVHmKQtGGQob.b/Nc7l9NO", b"$2a$07$zVHmKQtGGQob.b/Nc7l9NOBsj1dQpBA1HYNGpIETIByoNX9jc.hOi"),
  418. (b"", 8, b"zVHmKQtGGQob.b/Nc7l9NO", b"$2a$08$zVHmKQtGGQob.b/Nc7l9NOiLTUh/9MDpX86/DLyEzyiFjqjBFePgO"),
  419. ]
  420. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  421. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  422. self.assertEqual(x, result)
  423. bcrypt_check(password, result)
  424. def test_random_password_and_salt_short_pw(self):
  425. # password, cost, salt, bcrypt hash
  426. tvs = [
  427. (b"<.S.2K(Zq'", 4, b"VYAclAMpaXY/oqAo9yUpku", b"$2a$04$VYAclAMpaXY/oqAo9yUpkuWmoYywaPzyhu56HxXpVltnBIfmO9tgu"),
  428. (b"5.rApO%5jA", 5, b"kVNDrnYKvbNr5AIcxNzeIu", b"$2a$05$kVNDrnYKvbNr5AIcxNzeIuRcyIF5cZk6UrwHGxENbxP5dVv.WQM/G"),
  429. (b"oW++kSrQW^", 6, b"QLKkRMH9Am6irtPeSKN5sO", b"$2a$06$QLKkRMH9Am6irtPeSKN5sObJGr3j47cO6Pdf5JZ0AsJXuze0IbsNm"),
  430. (b"ggJ\\KbTnDG", 7, b"4H896R09bzjhapgCPS/LYu", b"$2a$07$4H896R09bzjhapgCPS/LYuMzAQluVgR5iu/ALF8L8Aln6lzzYXwbq"),
  431. (b"49b0:;VkH/", 8, b"hfvO2retKrSrx5f2RXikWe", b"$2a$08$hfvO2retKrSrx5f2RXikWeFWdtSesPlbj08t/uXxCeZoHRWDz/xFe"),
  432. (b">9N^5jc##'", 9, b"XZLvl7rMB3EvM0c1.JHivu", b"$2a$09$XZLvl7rMB3EvM0c1.JHivuIDPJWeNJPTVrpjZIEVRYYB/mF6cYgJK"),
  433. (b"\\$ch)s4WXp", 10, b"aIjpMOLK5qiS9zjhcHR5TO", b"$2a$10$aIjpMOLK5qiS9zjhcHR5TOU7v2NFDmcsBmSFDt5EHOgp/jeTF3O/q"),
  434. (b"RYoj\\_>2P7", 12, b"esIAHiQAJNNBrsr5V13l7.", b"$2a$12$esIAHiQAJNNBrsr5V13l7.RFWWJI2BZFtQlkFyiWXjou05GyuREZa"),
  435. ]
  436. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  437. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  438. self.assertEqual(x, result)
  439. bcrypt_check(password, result)
  440. def test_random_password_and_salt_long_pw(self):
  441. # password, cost, salt, bcrypt hash
  442. tvs = [
  443. (b"^Q&\"]A`%/A(BVGt>QaX0M-#<Q148&f", 4, b"vrRP5vQxyD4LrqiLd/oWRO", b"$2a$04$vrRP5vQxyD4LrqiLd/oWROgrrGINsw3gb4Ga5x2sn01jNmiLVECl6"),
  444. (b"nZa!rRf\\U;OL;R?>1ghq_+\":Y0CRmY", 5, b"YuQvhokOGVnevctykUYpKu", b"$2a$05$YuQvhokOGVnevctykUYpKutZD2pWeGGYn3auyLOasguMY3/0BbIyq"),
  445. (b"F%uN/j>[GuB7-jB'_Yj!Tnb7Y!u^6)", 6, b"5L3vpQ0tG9O7k5gQ8nAHAe", b"$2a$06$5L3vpQ0tG9O7k5gQ8nAHAe9xxQiOcOLh8LGcI0PLWhIznsDt.S.C6"),
  446. (b"Z>BobP32ub\"Cfe*Q<<WUq3rc=[GJr-", 7, b"hp8IdLueqE6qFh1zYycUZ.", b"$2a$07$hp8IdLueqE6qFh1zYycUZ.twmUH8eSTPQAEpdNXKMlwms9XfKqfea"),
  447. (b"Ik&8N['7*[1aCc1lOm8\\jWeD*H$eZM", 8, b"2ANDTYCB9m7vf0Prh7rSru", b"$2a$08$2ANDTYCB9m7vf0Prh7rSrupqpO3jJOkIz2oW/QHB4lCmK7qMytGV6"),
  448. (b"O)=%3[E$*q+>-q-=tRSjOBh8\\mLNW.", 9, b"nArqOfdCsD9kIbVnAixnwe", b"$2a$09$nArqOfdCsD9kIbVnAixnwe6s8QvyPYWtQBpEXKir2OJF9/oNBsEFe"),
  449. (b"/MH51`!BP&0tj3%YCA;Xk%e3S`o\\EI", 10, b"ePiAc.s.yoBi3B6p1iQUCe", b"$2a$10$ePiAc.s.yoBi3B6p1iQUCezn3mraLwpVJ5XGelVyYFKyp5FZn/y.u"),
  450. (b"ptAP\"mcg6oH.\";c0U2_oll.OKi<!ku", 12, b"aroG/pwwPj1tU5fl9a9pkO", b"$2a$12$aroG/pwwPj1tU5fl9a9pkO4rydAmkXRj/LqfHZOSnR6LGAZ.z.jwa"),
  451. ]
  452. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  453. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  454. self.assertEqual(x, result)
  455. bcrypt_check(password, result)
  456. def test_same_password_and_random_salt(self):
  457. # password, cost, salt, bcrypt hash
  458. tvs = [
  459. (b"Q/A:k3DP;X@=<0\"hg&9c", 4, b"wbgDTvLMtyjQlNK7fjqwyO", b"$2a$04$wbgDTvLMtyjQlNK7fjqwyOakBoACQuYh11.VsKNarF4xUIOBWgD6S"),
  460. (b"Q/A:k3DP;X@=<0\"hg&9c", 5, b"zbAaOmloOhxiKItjznRqru", b"$2a$05$zbAaOmloOhxiKItjznRqrunRqHlu3MAa7pMGv26Rr3WwyfGcwoRm6"),
  461. (b"Q/A:k3DP;X@=<0\"hg&9c", 6, b"aOK0bWUvLI0qLkc3ti5jyu", b"$2a$06$aOK0bWUvLI0qLkc3ti5jyuAIQoqRzuqoK09kQqQ6Ou/YKDhW50/qa"),
  462. ]
  463. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  464. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  465. self.assertEqual(x, result)
  466. bcrypt_check(password, result)
  467. def test_same_password_and_salt_increasing_cost_factor(self):
  468. # password, cost, salt, bcrypt hash
  469. tvs = [
  470. (b"o<&+X'F4AQ8H,LU,N`&r", 4, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$04$BK5u.QHk1Driey7bvnFTH.3smGwxd91PtoK2GxH5nZ7pcBsYX4lMq"),
  471. (b"o<&+X'F4AQ8H,LU,N`&r", 5, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$05$BK5u.QHk1Driey7bvnFTH.t5P.jZvFBMzDB1IY4PwkkRPOyVbEtFG"),
  472. (b"o<&+X'F4AQ8H,LU,N`&r", 6, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$06$BK5u.QHk1Driey7bvnFTH.6Ea1Z5db2p25CPXZbxb/3OyKQagg3pa"),
  473. (b"o<&+X'F4AQ8H,LU,N`&r", 7, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$07$BK5u.QHk1Driey7bvnFTH.sruuQi8Lhv/0LWKDvNp3AGFk7ltdkm6"),
  474. (b"o<&+X'F4AQ8H,LU,N`&r", 8, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$08$BK5u.QHk1Driey7bvnFTH.IE7KsaUzc4m7gzAMlyUPUeiYyACWe0q"),
  475. (b"o<&+X'F4AQ8H,LU,N`&r", 9, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$09$BK5u.QHk1Driey7bvnFTH.1v4Xj1dwkp44QNg0cVAoQt4FQMMrvnS"),
  476. (b"o<&+X'F4AQ8H,LU,N`&r", 10, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$10$BK5u.QHk1Driey7bvnFTH.ESINe9YntUMcVgFDfkC.Vbhc9vMhNX2"),
  477. (b"o<&+X'F4AQ8H,LU,N`&r", 12, b"BK5u.QHk1Driey7bvnFTH.", b"$2a$12$BK5u.QHk1Driey7bvnFTH.QM1/nnGe/f5cTzb6XTTi/vMzcAnycqG"),
  478. ]
  479. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  480. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  481. self.assertEqual(x, result)
  482. bcrypt_check(password, result)
  483. def test_long_passwords(self):
  484. # password, cost, salt, bcrypt hash
  485. tvs = [
  486. (b"g*3Q45=\"8NNgpT&mbMJ$Omfr.#ZeW?FP=CE$#roHd?97uL0F-]`?u73c\"\\[.\"*)qU34@VG",
  487. 4, b"T2XJ5MOWvHQZRijl8LIKkO", b"$2a$04$T2XJ5MOWvHQZRijl8LIKkOQKIyX75KBfuLsuRYOJz5OjwBNF2lM8a"),
  488. (b"\\M+*8;&QE=Ll[>5?Ui\"^ai#iQH7ZFtNMfs3AROnIncE9\"BNNoEgO[[*Yk8;RQ(#S,;I+aT",
  489. 5, b"wgkOlGNXIVE2fWkT3gyRoO", b"$2a$05$wgkOlGNXIVE2fWkT3gyRoOqWi4gbi1Wv2Q2Jx3xVs3apl1w.Wtj8C"),
  490. (b"M.E1=dt<.L0Q&p;94NfGm_Oo23+Kpl@M5?WIAL.[@/:'S)W96G8N^AWb7_smmC]>7#fGoB",
  491. 6, b"W9zTCl35nEvUukhhFzkKMe", b"$2a$06$W9zTCl35nEvUukhhFzkKMekjT9/pj7M0lihRVEZrX3m8/SBNZRX7i"),
  492. ]
  493. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  494. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  495. self.assertEqual(x, result)
  496. bcrypt_check(password, result)
  497. def test_increasing_password_length(self):
  498. # password, cost, salt, bcrypt hash
  499. tvs = [
  500. (b"a", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.l4WvgHIVg17ZawDIrDM2IjlE64GDNQS"),
  501. (b"aa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.AyUxBk.ThHlsLvRTH7IqcG7yVHJ3SXq"),
  502. (b"aaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.BxOVac5xPB6XFdRc/ZrzM9FgZkqmvbW"),
  503. (b"aaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.Qbr209bpCtfl5hN7UQlG/L4xiD3AKau"),
  504. (b"aaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.oWszihPjDZI0ypReKsaDOW1jBl7oOii"),
  505. (b"aaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ./k.Xxn9YiqtV/sxh3EHbnOHd0Qsq27K"),
  506. (b"aaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.PYJqRFQbgRbIjMd5VNKmdKS4sBVOyDe"),
  507. (b"aaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ..VMYfzaw1wP/SGxowpLeGf13fxCCt.q"),
  508. (b"aaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.5B0p054nO5WgAD1n04XslDY/bqY9RJi"),
  509. (b"aaaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.INBTgqm7sdlBJDg.J5mLMSRK25ri04y"),
  510. (b"aaaaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.s3y7CdFD0OR5p6rsZw/eZ.Dla40KLfm"),
  511. (b"aaaaaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.Jx742Djra6Q7PqJWnTAS.85c28g.Siq"),
  512. (b"aaaaaaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.oKMXW3EZcPHcUV0ib5vDBnh9HojXnLu"),
  513. (b"aaaaaaaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.w6nIjWpDPNSH5pZUvLjC1q25ONEQpeS"),
  514. (b"aaaaaaaaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.k1b2/r9A/hxdwKEKurg6OCn4MwMdiGq"),
  515. (b"aaaaaaaaaaaaaaaa", 4, b"5DCebwootqWMCp59ISrMJ.", b"$2a$04$5DCebwootqWMCp59ISrMJ.3prCNHVX1Ws.7Hm2bJxFUnQOX9f7DFa"),
  516. ]
  517. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  518. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  519. self.assertEqual(x, result)
  520. bcrypt_check(password, result)
  521. def test_non_ascii_characters(self):
  522. # password, cost, salt, bcrypt hash
  523. tvs = [
  524. ("àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝðÐ", 4, b"D3qS2aoTVyqM7z8v8crLm.", b"$2a$04$D3qS2aoTVyqM7z8v8crLm.3nKt4CzBZJbyFB.ZebmfCvRw7BGs.Xm"),
  525. ("àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝðÐ", 5, b"VA1FujiOCMPkUHQ8kF7IaO", b"$2a$05$VA1FujiOCMPkUHQ8kF7IaOg7NGaNvpxwWzSluQutxEVmbZItRTsAa"),
  526. ("àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝðÐ", 6, b"TXiaNrPeBSz5ugiQlehRt.", b"$2a$06$TXiaNrPeBSz5ugiQlehRt.gwpeDQnXWteQL4z2FulouBr6G7D9KUi"),
  527. ("âêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿ", 4, b"YTn1Qlvps8e1odqMn6G5x.", b"$2a$04$YTn1Qlvps8e1odqMn6G5x.85pqKql6w773EZJAExk7/BatYAI4tyO"),
  528. ("âêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿ", 5, b"C.8k5vJKD2NtfrRI9o17DO", b"$2a$05$C.8k5vJKD2NtfrRI9o17DOfIW0XnwItA529vJnh2jzYTb1QdoY0py"),
  529. ("âêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿ", 6, b"xqfRPj3RYAgwurrhcA6uRO", b"$2a$06$xqfRPj3RYAgwurrhcA6uROtGlXDp/U6/gkoDYHwlubtcVcNft5.vW"),
  530. ("ÄËÏÖÜŸåÅæÆœŒßçÇøØ¢¿¡€", 4, b"y8vGgMmr9EdyxP9rmMKjH.", b"$2a$04$y8vGgMmr9EdyxP9rmMKjH.wv2y3r7yRD79gykQtmb3N3zrwjKsyay"),
  531. ("ÄËÏÖÜŸåÅæÆœŒßçÇøØ¢¿¡€", 5, b"iYH4XIKAOOm/xPQs7xKP1u", b"$2a$05$iYH4XIKAOOm/xPQs7xKP1upD0cWyMn3Jf0ZWiizXbEkVpS41K1dcO"),
  532. ("ÄËÏÖÜŸåÅæÆœŒßçÇøØ¢¿¡€", 6, b"wCOob.D0VV8twafNDB2ape", b"$2a$06$wCOob.D0VV8twafNDB2apegiGD5nqF6Y1e6K95q6Y.R8C4QGd265q"),
  533. ("ΔημοσιεύθηκεστηνΕφημερίδατης", 4, b"E5SQtS6P4568MDXW7cyUp.", b"$2a$04$E5SQtS6P4568MDXW7cyUp.18wfDisKZBxifnPZjAI1d/KTYMfHPYO"),
  534. ("АБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмН", 4, b"03e26gQFHhQwRNf81/ww9.", b"$2a$04$03e26gQFHhQwRNf81/ww9.p1UbrNwxpzWjLuT.zpTLH4t/w5WhAhC"),
  535. ("нОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮю", 4, b"PHNoJwpXCfe32nUtLv2Upu", b"$2a$04$PHNoJwpXCfe32nUtLv2UpuhJXOzd4k7IdFwnEpYwfJVCZ/f/.8Pje"),
  536. ("電电電島岛島兔兔兎龜龟亀國国国區区区", 4, b"wU4/0i1TmNl2u.1jIwBX.u", b"$2a$04$wU4/0i1TmNl2u.1jIwBX.uZUaOL3Rc5ID7nlQRloQh6q5wwhV/zLW"),
  537. ("诶比伊艾弗豆贝尔维吾艾尺开艾丝维贼德", 4, b"P4kreGLhCd26d4WIy7DJXu", b"$2a$04$P4kreGLhCd26d4WIy7DJXusPkhxLvBouzV6OXkL5EB0jux0osjsry"),
  538. ]
  539. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  540. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  541. self.assertEqual(x, result)
  542. bcrypt_check(password, result)
  543. def test_special_case_salt(self):
  544. # password, cost, salt, bcrypt hash
  545. tvs = [
  546. ("-O_=*N!2JP", 4, b"......................", b"$2a$04$......................JjuKLOX9OOwo5PceZZXSkaLDvdmgb82"),
  547. ("7B[$Q<4b>U", 5, b"......................", b"$2a$05$......................DRiedDQZRL3xq5A5FL8y7/6NM8a2Y5W"),
  548. (">d5-I_8^.h", 6, b"......................", b"$2a$06$......................5Mq1Ng8jgDY.uHNU4h5p/x6BedzNH2W"),
  549. (")V`/UM/]1t", 4, b".OC/.OC/.OC/.OC/.OC/.O", b"$2a$04$.OC/.OC/.OC/.OC/.OC/.OQIvKRDAam.Hm5/IaV/.hc7P8gwwIbmi"),
  550. (":@t2.bWuH]", 5, b".OC/.OC/.OC/.OC/.OC/.O", b"$2a$05$.OC/.OC/.OC/.OC/.OC/.ONDbUvdOchUiKmQORX6BlkPofa/QxW9e"),
  551. ("b(#KljF5s\"", 6, b".OC/.OC/.OC/.OC/.OC/.O", b"$2a$06$.OC/.OC/.OC/.OC/.OC/.OHfTd9e7svOu34vi1PCvOcAEq07ST7.K"),
  552. ("@3YaJ^Xs]*", 4, b"eGA.eGA.eGA.eGA.eGA.e.", b"$2a$04$eGA.eGA.eGA.eGA.eGA.e.stcmvh.R70m.0jbfSFVxlONdj1iws0C"),
  553. ("'\"5\\!k*C(p", 5, b"eGA.eGA.eGA.eGA.eGA.e.", b"$2a$05$eGA.eGA.eGA.eGA.eGA.e.vR37mVSbfdHwu.F0sNMvgn8oruQRghy"),
  554. ("edEu7C?$'W", 6, b"eGA.eGA.eGA.eGA.eGA.e.", b"$2a$06$eGA.eGA.eGA.eGA.eGA.e.tSq0FN8MWHQXJXNFnHTPQKtA.n2a..G"),
  555. ("N7dHmg\\PI^", 4, b"999999999999999999999u", b"$2a$04$999999999999999999999uCZfA/pLrlyngNDMq89r1uUk.bQ9icOu"),
  556. ("\"eJuHh!)7*", 5, b"999999999999999999999u", b"$2a$05$999999999999999999999uj8Pfx.ufrJFAoWFLjapYBS5vVEQQ/hK"),
  557. ("ZeDRJ:_tu:", 6, b"999999999999999999999u", b"$2a$06$999999999999999999999u6RB0P9UmbdbQgjoQFEJsrvrKe.BoU6q"),
  558. ]
  559. for (idx, (password, cost, salt64, result)) in enumerate(tvs):
  560. x = bcrypt(password, cost, salt=_bcrypt_decode(salt64))
  561. self.assertEqual(x, result)
  562. bcrypt_check(password, result)
  563. class TestVectorsHKDFWycheproof(unittest.TestCase):
  564. def __init__(self, wycheproof_warnings):
  565. unittest.TestCase.__init__(self)
  566. self._wycheproof_warnings = wycheproof_warnings
  567. self._id = "None"
  568. def add_tests(self, filename):
  569. def filter_algo(root):
  570. algo_name = root['algorithm']
  571. if algo_name == "HKDF-SHA-1":
  572. return SHA1
  573. elif algo_name == "HKDF-SHA-256":
  574. return SHA256
  575. elif algo_name == "HKDF-SHA-384":
  576. return SHA384
  577. elif algo_name == "HKDF-SHA-512":
  578. return SHA512
  579. else:
  580. raise ValueError("Unknown algorithm " + algo_name)
  581. def filter_size(unit):
  582. return int(unit['size'])
  583. result = load_test_vectors_wycheproof(("Protocol", "wycheproof"),
  584. filename,
  585. "Wycheproof HMAC (%s)" % filename,
  586. root_tag={'hash_module': filter_algo},
  587. unit_tag={'size': filter_size})
  588. return result
  589. def setUp(self):
  590. self.tv = []
  591. self.add_tests("hkdf_sha1_test.json")
  592. self.add_tests("hkdf_sha256_test.json")
  593. self.add_tests("hkdf_sha384_test.json")
  594. self.add_tests("hkdf_sha512_test.json")
  595. def shortDescription(self):
  596. return self._id
  597. def warn(self, tv):
  598. if tv.warning and self._wycheproof_warnings:
  599. import warnings
  600. warnings.warn("Wycheproof warning: %s (%s)" % (self._id, tv.comment))
  601. def test_verify(self, tv):
  602. self._id = "Wycheproof HKDF Test #%d (%s, %s)" % (tv.id, tv.comment, tv.filename)
  603. try:
  604. key = HKDF(tv.ikm, tv.size, tv.salt, tv.hash_module, 1, tv.info)
  605. except ValueError:
  606. assert not tv.valid
  607. else:
  608. if key != tv.okm:
  609. assert not tv.valid
  610. else:
  611. assert tv.valid
  612. self.warn(tv)
  613. def runTest(self):
  614. for tv in self.tv:
  615. self.test_verify(tv)
  616. def load_hash_by_name(hash_name):
  617. return __import__("Crypto.Hash." + hash_name, globals(), locals(), ["new"])
  618. class SP800_108_Counter_Tests(unittest.TestCase):
  619. def test_negative_zeroes(self):
  620. def prf(s, x):
  621. return HMAC.new(s, x, SHA256).digest()
  622. try:
  623. _ = SP800_108_Counter(b'0' * 16, 1, prf, label=b'A\x00B')
  624. except ValueError:
  625. self.fail('SP800_108_Counter failed with zero in label')
  626. self.assertRaises(ValueError, SP800_108_Counter, b'0' * 16, 1, prf,
  627. context=b'A\x00B')
  628. def test_multiple_keys(self):
  629. def prf(s, x):
  630. return HMAC.new(s, x, SHA256).digest()
  631. key = b'0' * 16
  632. expected = SP800_108_Counter(key, 2*3*23, prf)
  633. for r in (1, 2, 3, 23):
  634. dks = SP800_108_Counter(key, r, prf, 138//r)
  635. self.assertEqual(len(dks), 138//r)
  636. self.assertEqual(len(dks[0]), r)
  637. self.assertEqual(b''.join(dks), expected)
  638. def add_tests_sp800_108_counter(cls):
  639. test_vectors_sp800_108_counter = load_test_vectors(("Protocol", ),
  640. "KDF_SP800_108_COUNTER.txt",
  641. "NIST SP 800 108 KDF Counter Mode",
  642. {'count': lambda x: int(x)},
  643. ) or []
  644. mac_type = None
  645. for idx, tv in enumerate(test_vectors_sp800_108_counter):
  646. if isinstance(tv, str):
  647. res = re.match(r"\[HMAC-(SHA-[0-9]+)\]", tv)
  648. if res:
  649. hash_name = res.group(1).replace("-", "")
  650. hash_module = load_hash_by_name(hash_name)
  651. mac_type = "hmac"
  652. continue
  653. res = re.match(r"\[CMAC-AES-128\]", tv)
  654. if res:
  655. mac_type = "cmac"
  656. continue
  657. assert res
  658. if mac_type == "hmac":
  659. def prf(s, x, hash_module=hash_module):
  660. return HMAC.new(s, x, hash_module).digest()
  661. elif mac_type == "cmac":
  662. def prf(s, x, hash_module=hash_module):
  663. return CMAC.new(s, x, AES).digest()
  664. continue
  665. def kdf_test(self, prf=prf, kin=tv.kin, label=tv.label,
  666. context=tv.context, kout=tv.kout, count=tv.count):
  667. result = SP800_108_Counter(kin, len(kout), prf, 1, label, context)
  668. assert(len(result) == len(kout))
  669. self.assertEqual(result, kout)
  670. setattr(cls, "test_kdf_sp800_108_counter_%d" % idx, kdf_test)
  671. add_tests_sp800_108_counter(SP800_108_Counter_Tests)
  672. def get_tests(config={}):
  673. wycheproof_warnings = config.get('wycheproof_warnings')
  674. if not config.get('slow_tests'):
  675. PBKDF2_Tests._testData = PBKDF2_Tests._testData[:3]
  676. scrypt_Tests.data = scrypt_Tests.data[:3]
  677. tests = []
  678. tests += list_test_cases(PBKDF1_Tests)
  679. tests += list_test_cases(PBKDF2_Tests)
  680. tests += list_test_cases(S2V_Tests)
  681. tests += list_test_cases(HKDF_Tests)
  682. tests += [TestVectorsHKDFWycheproof(wycheproof_warnings)]
  683. tests += list_test_cases(scrypt_Tests)
  684. tests += list_test_cases(bcrypt_Tests)
  685. tests += list_test_cases(SP800_108_Counter_Tests)
  686. return tests
  687. if __name__ == '__main__':
  688. suite = lambda: unittest.TestSuite(get_tests())
  689. unittest.main(defaultTest='suite')