crypto_unittests.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <config.h>
  15. #include <gtest/gtest.h>
  16. #include <cryptolink/crypto.h>
  17. #include <dns/buffer.h>
  18. #include <exceptions/exceptions.h>
  19. #include <boost/scoped_ptr.hpp>
  20. using namespace isc::dns;
  21. using namespace isc::cryptolink;
  22. namespace {
  23. void checkData(const uint8_t* data, const uint8_t* expected,
  24. size_t len) {
  25. for (size_t i = 0; i < len; ++i) {
  26. ASSERT_EQ(expected[i], data[i]);
  27. }
  28. }
  29. void checkBuffer(const OutputBuffer& buf, const uint8_t* expected,
  30. size_t len)
  31. {
  32. ASSERT_EQ(len, buf.getLength());
  33. checkData(static_cast<const uint8_t*>(buf.getData()), expected,
  34. len);
  35. }
  36. // Sign and verify with the convenience functions
  37. void doHMACTestConv(const std::string& data,
  38. const void* secret,
  39. size_t secret_len,
  40. const HMAC::HashAlgorithm hash_algorithm,
  41. const uint8_t* expected_hmac,
  42. size_t hmac_len) {
  43. OutputBuffer data_buf(data.size());
  44. data_buf.writeData(data.c_str(), data.size());
  45. OutputBuffer hmac_sig(0);
  46. // Sign it
  47. signHMAC(data_buf.getData(), data_buf.getLength(),
  48. secret, secret_len, hash_algorithm, hmac_sig, hmac_len);
  49. // Check if the signature is what we expect
  50. checkBuffer(hmac_sig, expected_hmac, hmac_len);
  51. // Check whether we can verify it ourselves
  52. EXPECT_TRUE(verifyHMAC(data_buf.getData(), data_buf.getLength(),
  53. secret, secret_len, hash_algorithm,
  54. hmac_sig.getData(),
  55. hmac_sig.getLength()));
  56. // Change the sig by flipping the first octet, and check
  57. // whether verification fails then
  58. hmac_sig.writeUint8At(~hmac_sig[0], 0);
  59. EXPECT_FALSE(verifyHMAC(data_buf.getData(), data_buf.getLength(),
  60. secret, secret_len, hash_algorithm,
  61. hmac_sig.getData(),
  62. hmac_sig.getLength()));
  63. }
  64. // Sign and verify with an instantiation of an HMAC object
  65. void doHMACTestDirect(const std::string& data,
  66. const void* secret,
  67. size_t secret_len,
  68. const HMAC::HashAlgorithm hash_algorithm,
  69. const uint8_t* expected_hmac,
  70. size_t hmac_len) {
  71. OutputBuffer data_buf(data.size());
  72. data_buf.writeData(data.c_str(), data.size());
  73. OutputBuffer hmac_sig(1);
  74. CryptoLink& crypto = CryptoLink::getCryptoLink();
  75. // Sign it
  76. boost::scoped_ptr<HMAC> hmac_sign(crypto.createHMAC(secret,
  77. secret_len,
  78. hash_algorithm));
  79. hmac_sign->update(data_buf.getData(), data_buf.getLength());
  80. hmac_sign->sign(hmac_sig, hmac_len);
  81. // Check if the signature is what we expect
  82. checkBuffer(hmac_sig, expected_hmac, hmac_len);
  83. // Check whether we can verify it ourselves
  84. boost::scoped_ptr<HMAC> hmac_verify(crypto.createHMAC(secret,
  85. secret_len,
  86. hash_algorithm));
  87. hmac_verify->update(data_buf.getData(), data_buf.getLength());
  88. EXPECT_TRUE(hmac_verify->verify(hmac_sig.getData(),
  89. hmac_sig.getLength()));
  90. // Change the sig by flipping the first octet, and check
  91. // whether verification fails then
  92. hmac_sig.writeUint8At(~hmac_sig[0], 0);
  93. EXPECT_FALSE(hmac_verify->verify(hmac_sig.getData(),
  94. hmac_sig.getLength()));
  95. }
  96. void doHMACTestVector(const std::string& data,
  97. const void* secret,
  98. size_t secret_len,
  99. const HMAC::HashAlgorithm hash_algorithm,
  100. const uint8_t* expected_hmac,
  101. size_t hmac_len) {
  102. CryptoLink& crypto = CryptoLink::getCryptoLink();
  103. boost::scoped_ptr<HMAC> hmac_sign(crypto.createHMAC(secret,
  104. secret_len,
  105. hash_algorithm));
  106. hmac_sign->update(data.c_str(), data.size());
  107. std::vector<uint8_t> sig = hmac_sign->sign(hmac_len);
  108. ASSERT_EQ(hmac_len, sig.size());
  109. checkData(&sig[0], expected_hmac, hmac_len);
  110. boost::scoped_ptr<HMAC> hmac_verify(crypto.createHMAC(secret,
  111. secret_len,
  112. hash_algorithm));
  113. hmac_verify->update(data.c_str(), data.size());
  114. EXPECT_TRUE(hmac_verify->verify(&sig[0], sig.size()));
  115. sig[0] = ~sig[0];
  116. EXPECT_FALSE(hmac_verify->verify(&sig[0], sig.size()));
  117. }
  118. void doHMACTestArray(const std::string& data,
  119. const void* secret,
  120. size_t secret_len,
  121. const HMAC::HashAlgorithm hash_algorithm,
  122. const uint8_t* expected_hmac,
  123. size_t hmac_len) {
  124. CryptoLink& crypto = CryptoLink::getCryptoLink();
  125. boost::scoped_ptr<HMAC> hmac_sign(crypto.createHMAC(secret,
  126. secret_len,
  127. hash_algorithm));
  128. hmac_sign->update(data.c_str(), data.size());
  129. // note: this is not exception-safe, and will leak, but
  130. // if there is an unexpected exception in the code below we
  131. // have more important things to fix.
  132. uint8_t* sig = new uint8_t[hmac_len];
  133. hmac_sign->sign(sig, hmac_len);
  134. checkData(sig, expected_hmac, hmac_len);
  135. boost::scoped_ptr<HMAC> hmac_verify(crypto.createHMAC(secret,
  136. secret_len,
  137. hash_algorithm));
  138. hmac_verify->update(data.c_str(), data.size());
  139. EXPECT_TRUE(hmac_verify->verify(sig, hmac_len));
  140. sig[0] = ~sig[0];
  141. EXPECT_FALSE(hmac_verify->verify(sig, hmac_len));
  142. delete[] sig;
  143. }
  144. void doHMACTest(const std::string& data,
  145. const void* secret,
  146. size_t secret_len,
  147. const HMAC::HashAlgorithm hash_algorithm,
  148. const uint8_t* expected_hmac,
  149. size_t hmac_len) {
  150. doHMACTestConv(data, secret, secret_len, hash_algorithm,
  151. expected_hmac, hmac_len);
  152. doHMACTestDirect(data, secret, secret_len, hash_algorithm,
  153. expected_hmac, hmac_len);
  154. doHMACTestVector(data, secret, secret_len, hash_algorithm,
  155. expected_hmac, hmac_len);
  156. doHMACTestArray(data, secret, secret_len, hash_algorithm,
  157. expected_hmac, hmac_len);
  158. }
  159. }
  160. //
  161. // Test values taken from RFC 2202
  162. //
  163. TEST(CryptoLinkTest, HMAC_MD5_RFC2202_SIGN) {
  164. const uint8_t secret[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  165. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  166. 0x0b, 0x0b };
  167. const uint8_t hmac_expected[] = { 0x92, 0x94, 0x72, 0x7a, 0x36,
  168. 0x38, 0xbb, 0x1c, 0x13, 0xf4,
  169. 0x8e, 0xf8, 0x15, 0x8b, 0xfc,
  170. 0x9d };
  171. doHMACTest("Hi There", secret, 16, HMAC::MD5, hmac_expected, 16);
  172. const uint8_t hmac_expected2[] = { 0x75, 0x0c, 0x78, 0x3e, 0x6a,
  173. 0xb0, 0xb5, 0x03, 0xea, 0xa8,
  174. 0x6e, 0x31, 0x0a, 0x5d, 0xb7,
  175. 0x38 };
  176. doHMACTest("what do ya want for nothing?", "Jefe", 4, HMAC::MD5,
  177. hmac_expected2, 16);
  178. const std::string data3(50, 0xdd);
  179. const uint8_t secret3[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  180. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  181. 0xaa, 0xaa, 0xaa, 0xaa };
  182. const uint8_t hmac_expected3[] = { 0x56, 0xbe, 0x34, 0x52, 0x1d,
  183. 0x14, 0x4c, 0x88, 0xdb, 0xb8,
  184. 0xc7, 0x33, 0xf0, 0xe8, 0xb3,
  185. 0xf6};
  186. doHMACTest(data3, secret3, 16, HMAC::MD5, hmac_expected3, 16);
  187. const std::string data4(50, 0xcd);
  188. const uint8_t secret4[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  189. 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
  190. 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
  191. 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  192. 0x19 };
  193. const uint8_t hmac_expected4[] = { 0x69, 0x7e, 0xaf, 0x0a, 0xca,
  194. 0x3a, 0x3a, 0xea, 0x3a, 0x75,
  195. 0x16, 0x47, 0x46, 0xff, 0xaa,
  196. 0x79 };
  197. doHMACTest(data4, secret4, 25, HMAC::MD5, hmac_expected4, 16);
  198. const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  199. 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  200. 0x0c, 0x0c, 0x0c, 0x0c };
  201. const uint8_t hmac_expected5[] = { 0x56, 0x46, 0x1e, 0xf2, 0x34,
  202. 0x2e, 0xdc, 0x00, 0xf9, 0xba,
  203. 0xb9, 0x95, 0x69, 0x0e, 0xfd,
  204. 0x4c };
  205. doHMACTest("Test With Truncation", secret5, 16, HMAC::MD5,
  206. hmac_expected5, 16);
  207. doHMACTest("Test With Truncation", secret5, 16, HMAC::MD5,
  208. hmac_expected5, 12);
  209. const std::string secret6(80, 0xaa);
  210. const uint8_t hmac_expected6[] = { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b,
  211. 0xd7, 0xbf, 0x8f, 0x0b, 0x62,
  212. 0xe6, 0xce, 0x61, 0xb9, 0xd0,
  213. 0xcd };
  214. doHMACTest("Test Using Larger Than Block-Size Key - Hash Key First",
  215. secret6.c_str(), 80, HMAC::MD5, hmac_expected6, 16);
  216. // same secret as for test 6
  217. const uint8_t hmac_expected7[] = { 0x6f, 0x63, 0x0f, 0xad, 0x67,
  218. 0xcd, 0xa0, 0xee, 0x1f, 0xb1,
  219. 0xf5, 0x62, 0xdb, 0x3a, 0xa5,
  220. 0x3e };
  221. doHMACTest("Test Using Larger Than Block-Size Key and Larger Than "
  222. "One Block-Size Data",
  223. secret6.c_str(), 80, HMAC::MD5, hmac_expected7, 16);
  224. }
  225. //
  226. // Test values taken from RFC 2202
  227. //
  228. TEST(CryptoLinkTest, HMAC_SHA1_RFC2202_SIGN) {
  229. const uint8_t secret[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  230. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  231. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
  232. const uint8_t hmac_expected[] = { 0xb6, 0x17, 0x31, 0x86, 0x55,
  233. 0x05, 0x72, 0x64, 0xe2, 0x8b,
  234. 0xc0, 0xb6, 0xfb, 0x37, 0x8c,
  235. 0x8e, 0xf1, 0x46, 0xbe, 0x00 };
  236. doHMACTest("Hi There", secret, 20, HMAC::SHA1, hmac_expected, 20);
  237. const uint8_t hmac_expected2[] = { 0xef, 0xfc, 0xdf, 0x6a, 0xe5,
  238. 0xeb, 0x2f, 0xa2, 0xd2, 0x74,
  239. 0x16, 0xd5, 0xf1, 0x84, 0xdf,
  240. 0x9c, 0x25, 0x9a, 0x7c, 0x79 };
  241. doHMACTest("what do ya want for nothing?", "Jefe", 4, HMAC::SHA1,
  242. hmac_expected2, 20);
  243. const std::string data3(50, 0xdd);
  244. const uint8_t secret3[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  245. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  246. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  247. 0xaa, 0xaa };
  248. const uint8_t hmac_expected3[] = { 0x12, 0x5d, 0x73, 0x42, 0xb9,
  249. 0xac, 0x11, 0xcd, 0x91, 0xa3,
  250. 0x9a, 0xf4, 0x8a, 0xa1, 0x7b,
  251. 0x4f, 0x63, 0xf1, 0x75, 0xd3 };
  252. doHMACTest(data3, secret3, 20, HMAC::SHA1, hmac_expected3, 20);
  253. const std::string data4(50, 0xcd);
  254. const uint8_t secret4[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  255. 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
  256. 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
  257. 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  258. 0x19 };
  259. const uint8_t hmac_expected4[] = { 0x4c, 0x90, 0x07, 0xf4, 0x02,
  260. 0x62, 0x50, 0xc6, 0xbc, 0x84,
  261. 0x14, 0xf9, 0xbf, 0x50, 0xc8,
  262. 0x6c, 0x2d, 0x72, 0x35, 0xda };
  263. doHMACTest(data4, secret4, 25, HMAC::SHA1, hmac_expected4, 20);
  264. const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  265. 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  266. 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  267. 0x0c, 0x0c };
  268. const uint8_t hmac_expected5[] = { 0x4c, 0x1a, 0x03, 0x42, 0x4b,
  269. 0x55, 0xe0, 0x7f, 0xe7, 0xf2,
  270. 0x7b, 0xe1, 0xd5, 0x8b, 0xb9,
  271. 0x32, 0x4a, 0x9a, 0x5a, 0x04 };
  272. doHMACTest("Test With Truncation", secret5, 20, HMAC::SHA1,
  273. hmac_expected5, 20);
  274. doHMACTest("Test With Truncation", secret5, 20, HMAC::SHA1,
  275. hmac_expected5, 12);
  276. const std::string secret6(80, 0xaa);
  277. const uint8_t hmac_expected6[] = { 0xaa, 0x4a, 0xe5, 0xe1, 0x52,
  278. 0x72, 0xd0, 0x0e, 0x95, 0x70,
  279. 0x56, 0x37, 0xce, 0x8a, 0x3b,
  280. 0x55, 0xed, 0x40, 0x21, 0x12 };
  281. doHMACTest("Test Using Larger Than Block-Size Key - Hash Key First",
  282. secret6.c_str(), 80, HMAC::SHA1, hmac_expected6, 20);
  283. // same secret as for test 6
  284. const uint8_t hmac_expected7[] = { 0xe8, 0xe9, 0x9d, 0x0f, 0x45,
  285. 0x23, 0x7d, 0x78, 0x6d, 0x6b,
  286. 0xba, 0xa7, 0x96, 0x5c, 0x78,
  287. 0x08, 0xbb, 0xff, 0x1a, 0x91 };
  288. doHMACTest("Test Using Larger Than Block-Size Key and Larger Than "
  289. "One Block-Size Data",
  290. secret6.c_str(), 80, HMAC::SHA1, hmac_expected7, 20);
  291. }
  292. //
  293. // Test values taken from RFC 4231
  294. //
  295. TEST(CryptoLinkTest, HMAC_SHA256_RFC2202_SIGN) {
  296. const uint8_t secret[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  297. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  298. 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
  299. const uint8_t hmac_expected[] = { 0xb0, 0x34, 0x4c, 0x61, 0xd8,
  300. 0xdb, 0x38, 0x53, 0x5c, 0xa8,
  301. 0xaf, 0xce, 0xaf, 0x0b, 0xf1,
  302. 0x2b, 0x88, 0x1d, 0xc2, 0x00,
  303. 0xc9, 0x83, 0x3d, 0xa7, 0x26,
  304. 0xe9, 0x37, 0x6c, 0x2e, 0x32,
  305. 0xcf, 0xf7 };
  306. doHMACTest("Hi There", secret, 20, HMAC::SHA256, hmac_expected, 32);
  307. const uint8_t hmac_expected2[] = { 0x5b, 0xdc, 0xc1, 0x46, 0xbf,
  308. 0x60, 0x75, 0x4e, 0x6a, 0x04,
  309. 0x24, 0x26, 0x08, 0x95, 0x75,
  310. 0xc7, 0x5a, 0x00, 0x3f, 0x08,
  311. 0x9d, 0x27, 0x39, 0x83, 0x9d,
  312. 0xec, 0x58, 0xb9, 0x64, 0xec,
  313. 0x38, 0x43 };
  314. doHMACTest("what do ya want for nothing?", "Jefe", 4, HMAC::SHA256,
  315. hmac_expected2, 32);
  316. const std::string data3(50, 0xdd);
  317. const uint8_t secret3[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  318. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  319. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  320. 0xaa, 0xaa };
  321. const uint8_t hmac_expected3[] = { 0x77, 0x3e, 0xa9, 0x1e, 0x36,
  322. 0x80, 0x0e, 0x46, 0x85, 0x4d,
  323. 0xb8, 0xeb, 0xd0, 0x91, 0x81,
  324. 0xa7, 0x29, 0x59, 0x09, 0x8b,
  325. 0x3e, 0xf8, 0xc1, 0x22, 0xd9,
  326. 0x63, 0x55, 0x14, 0xce, 0xd5,
  327. 0x65, 0xfe };
  328. doHMACTest(data3, secret3, 20, HMAC::SHA256, hmac_expected3, 32);
  329. const std::string data4(50, 0xcd);
  330. const uint8_t secret4[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  331. 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
  332. 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
  333. 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  334. 0x19 };
  335. const uint8_t hmac_expected4[] = { 0x82, 0x55, 0x8a, 0x38, 0x9a,
  336. 0x44, 0x3c, 0x0e, 0xa4, 0xcc,
  337. 0x81, 0x98, 0x99, 0xf2, 0x08,
  338. 0x3a, 0x85, 0xf0, 0xfa, 0xa3,
  339. 0xe5, 0x78, 0xf8, 0x07, 0x7a,
  340. 0x2e, 0x3f, 0xf4, 0x67, 0x29,
  341. 0x66, 0x5b };
  342. doHMACTest(data4, secret4, 25, HMAC::SHA256, hmac_expected4, 32);
  343. const uint8_t secret5[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  344. 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  345. 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  346. 0x0c, 0x0c };
  347. const uint8_t hmac_expected5[] = { 0xa3, 0xb6, 0x16, 0x74, 0x73,
  348. 0x10, 0x0e, 0xe0, 0x6e, 0x0c,
  349. 0x79, 0x6c, 0x29, 0x55, 0x55,
  350. 0x2b };
  351. doHMACTest("Test With Truncation", secret5, 20, HMAC::SHA256,
  352. hmac_expected5, 16);
  353. const std::string secret6(131, 0xaa);
  354. const uint8_t hmac_expected6[] = { 0x60, 0xe4, 0x31, 0x59, 0x1e,
  355. 0xe0, 0xb6, 0x7f, 0x0d, 0x8a,
  356. 0x26, 0xaa, 0xcb, 0xf5, 0xb7,
  357. 0x7f, 0x8e, 0x0b, 0xc6, 0x21,
  358. 0x37, 0x28, 0xc5, 0x14, 0x05,
  359. 0x46, 0x04, 0x0f, 0x0e, 0xe3,
  360. 0x7f, 0x54 };
  361. doHMACTest("Test Using Larger Than Block-Size Key - Hash Key First",
  362. secret6.c_str(), 131, HMAC::SHA256, hmac_expected6, 32);
  363. // Same secret as test 6
  364. const uint8_t hmac_expected7[] = { 0x9b, 0x09, 0xff, 0xa7, 0x1b,
  365. 0x94, 0x2f, 0xcb, 0x27, 0x63,
  366. 0x5f, 0xbc, 0xd5, 0xb0, 0xe9,
  367. 0x44, 0xbf, 0xdc, 0x63, 0x64,
  368. 0x4f, 0x07, 0x13, 0x93, 0x8a,
  369. 0x7f, 0x51, 0x53, 0x5c, 0x3a,
  370. 0x35, 0xe2 };
  371. doHMACTest("This is a test using a larger than block-size key and a"
  372. " larger than block-size data. The key needs to be hashe"
  373. "d before being used by the HMAC algorithm.",
  374. secret6.c_str(), 131, HMAC::SHA256, hmac_expected7, 32);
  375. }
  376. namespace {
  377. size_t
  378. sigVectorLength(HMAC::HashAlgorithm alg, size_t len) {
  379. boost::scoped_ptr<HMAC> hmac_sign(
  380. CryptoLink::getCryptoLink().createHMAC("asdf", 4, alg));
  381. hmac_sign->update("asdf", 4);
  382. const std::vector<uint8_t> sig = hmac_sign->sign(len);
  383. return sig.size();
  384. }
  385. size_t
  386. sigBufferLength(HMAC::HashAlgorithm alg, size_t len) {
  387. boost::scoped_ptr<HMAC> hmac_sign(
  388. CryptoLink::getCryptoLink().createHMAC("asdf", 4, alg));
  389. hmac_sign->update("asdf", 4);
  390. OutputBuffer sig(0);
  391. hmac_sign->sign(sig, len);
  392. return sig.getLength();
  393. }
  394. }
  395. TEST(CryptoLinkTest, HMACSigLengthArgument)
  396. {
  397. std::vector<uint8_t> sig;
  398. EXPECT_EQ(16, sigVectorLength(HMAC::MD5, 0));
  399. EXPECT_EQ(8, sigVectorLength(HMAC::MD5, 8));
  400. EXPECT_EQ(16, sigVectorLength(HMAC::MD5, 16));
  401. EXPECT_EQ(16, sigVectorLength(HMAC::MD5, 40));
  402. EXPECT_EQ(16, sigVectorLength(HMAC::MD5, 2000));
  403. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 0));
  404. EXPECT_EQ(8, sigBufferLength(HMAC::SHA1, 8));
  405. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 20));
  406. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 40));
  407. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 2000));
  408. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 0));
  409. EXPECT_EQ(8, sigBufferLength(HMAC::SHA256, 8));
  410. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 32));
  411. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 40));
  412. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 3200));
  413. EXPECT_EQ(16, sigBufferLength(HMAC::MD5, 0));
  414. EXPECT_EQ(8, sigBufferLength(HMAC::MD5, 8));
  415. EXPECT_EQ(16, sigBufferLength(HMAC::MD5, 16));
  416. EXPECT_EQ(16, sigBufferLength(HMAC::MD5, 40));
  417. EXPECT_EQ(16, sigBufferLength(HMAC::MD5, 2000));
  418. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 0));
  419. EXPECT_EQ(8, sigBufferLength(HMAC::SHA1, 8));
  420. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 20));
  421. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 40));
  422. EXPECT_EQ(20, sigBufferLength(HMAC::SHA1, 2000));
  423. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 0));
  424. EXPECT_EQ(8, sigBufferLength(HMAC::SHA256, 8));
  425. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 32));
  426. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 40));
  427. EXPECT_EQ(32, sigBufferLength(HMAC::SHA256, 3200));
  428. }
  429. TEST(CryptoLinkTest, BadKey) {
  430. OutputBuffer data_buf(0);
  431. OutputBuffer hmac_sig(0);
  432. CryptoLink& crypto = CryptoLink::getCryptoLink();
  433. EXPECT_THROW(crypto.createHMAC(NULL, 0, HMAC::MD5), BadKey);
  434. EXPECT_THROW(crypto.createHMAC(NULL, 0, HMAC::UNKNOWN), UnsupportedAlgorithm);
  435. EXPECT_THROW(signHMAC(data_buf.getData(), data_buf.getLength(),
  436. NULL, 0, HMAC::MD5, hmac_sig), BadKey);
  437. EXPECT_THROW(signHMAC(data_buf.getData(), data_buf.getLength(),
  438. NULL, 0, HMAC::UNKNOWN, hmac_sig),
  439. UnsupportedAlgorithm);
  440. EXPECT_THROW(verifyHMAC(data_buf.getData(), data_buf.getLength(),
  441. NULL, 0, HMAC::MD5, hmac_sig.getData(),
  442. hmac_sig.getLength()), BadKey);
  443. EXPECT_THROW(verifyHMAC(data_buf.getData(), data_buf.getLength(),
  444. NULL, 0, HMAC::UNKNOWN, hmac_sig.getData(),
  445. hmac_sig.getLength()),
  446. UnsupportedAlgorithm);
  447. }
  448. TEST(CryptoLinkTest, Singleton) {
  449. CryptoLink& c1 = CryptoLink::getCryptoLink();
  450. CryptoLink& c2 = CryptoLink::getCryptoLink();
  451. ASSERT_EQ(&c1, &c2);
  452. }