cryptotests.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. /*
  14. * cryptohelper regression tests
  15. *
  16. */
  17. #ifdef _USE_CPPUNIT
  18. #include <functional>
  19. #include "jencrypt.hpp"
  20. #include "unittests.hpp"
  21. #include "digisign.hpp"
  22. #include "pke.hpp"
  23. #include "ske.hpp"
  24. /* ============================================================= */
  25. const char * privKey =
  26. "-----BEGIN RSA PRIVATE KEY-----\n"
  27. "MIIEpAIBAAKCAQEA1SISNsSwg81TClnjGtVV61cYOmGWgKbbnpvSOqbZWMHs9W4L\n"
  28. "g2waNbGnQ3G+l7alWiMRV4qTjhkrdVRuvTxLOGOAfAhGB4Y5txDUNdTwuSp+Gpuq\n"
  29. "coYOmQWW4IIrjIOZMlamZQcIs7p/2CzfoLQHNuFuBeR+MLDMsMO7O42N+pcFWqPC\n"
  30. "plmRIkDWB2ru+DpJcaTtts/16f1/nf4KbMmpVlObWP/l48/XZjythzQir5AV6W13\n"
  31. "VM7MFToQqPxjy/c9F06/RjiW7sFv/r58pNsPk0iWcL0wBJ0GHZRGsCNOKMl08qow\n"
  32. "jynIVMKhIADYFXm84r69R1CO9KocixnqsH29uQIDAQABAoIBAEMCdFGN46V837fo\n"
  33. "bPPZ0Sqt9msclZIbY/9pJF7WaI10Y0kC8VG/ojnxghI9Z9wRS8mcLu6kHiJWHYjF\n"
  34. "JBARLeErv5C/lSz2cZzyCJZoPcsp5f39pUheh6Zq0HYD1ydVlMvz3Fr1LDI918Yi\n"
  35. "zaicEYyasdnebiJm4+RLlclyhwoa8CeRNLbLRoHcL7mu7sHHDMIWS86P/axfAnZ4\n"
  36. "yk2DKqjFflgd1zmRW5JLj6phb80ehuFIMJQ/Llwm4LY3uvg11D8c8ZDXQnMVSAIE\n"
  37. "fV5X9dtS1LCexYIpRmLj/LTAYZbQSdmE2w2lXLnDewiFD57eJNjYK9O0+iZg/Nfj\n"
  38. "i/95tVUCgYEA+D7N/LmWil3n/jz6zmrZPj+j7fjiZ+YiJ1mIOROvnlHhOgGzzjV5\n"
  39. "hFAVET9vlqSQoOelK9aYVEl9yfi9fRq1TUGLucS9+x5Urt1FBWyJw5cgdkpUIY4k\n"
  40. "pa9CCvnKrOieL+Rs4mU6XKqwx8iswv5PeOzW6/aMwbloVsAkYxEFiRsCgYEA28p6\n"
  41. "JDMO0pJE3rmesyxpLMayGCtpiFhbhuoIsveae2Hf6Qe7Bg73FEMHeDnjgXzpN8IY\n"
  42. "YgAMXglRsN09lPRc7cxUWdsr0slu8J/ouCaYu7l0i+Y1fp3YWLnUp56T45GGJPEI\n"
  43. "ro6EIhyX2J7abFV5qNHzI+AnlPubL8XCzaUwNbsCgYEA2F/NpYGSAIq3Ynd+WJrz\n"
  44. "Pfm0hgDQPqVtkYTNYoqRIVrXCHthYNRlVXmD02PKfLB1y3n9EsfaQGVKOdgQOdIk\n"
  45. "wvDlvAcLXK1kPIJq3b5sGcpJJjHFQPYnZS7sTqrJCIs9Dht4+KApDYpNyeVVCCUn\n"
  46. "2gv9jPB6YYScuDiDvsGgZI8CgYBUg1bT9I4Oig/RVK6hVsJaZUy13nuF4fPPvM37\n"
  47. "gxnzt37RrBdODRMUx3Fn2VqRv+YteoTFqh8XSZ4P1AKJ9CyHg7orkwsW0j3GaLaj\n"
  48. "mLPB+13FLZAET82Q0GPk0CUtrBdYvRYJiONl+nio4uw6G+Pb9l73vIl70AOsKu7t\n"
  49. "BEe1YQKBgQDeW3xAP3ceoJAW5qfnTzCY20wfs/epVSczqm2ZBrLhnY2l0FgefXCg\n"
  50. "eLLmQ8M0zCPrEIxsz11QmGunOVE0/boEOShYbOVTjAEES9a/+FHg0gyIP4zU8WZc\n"
  51. "dye0XkCOCkcGIwdas3fwf+O0lwZc+dvPdKVak+e8qL9aPgiQCb2/ww==\n"
  52. "-----END RSA PRIVATE KEY-----\n";
  53. const char * pubKey =
  54. "-----BEGIN PUBLIC KEY-----\n"
  55. "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1SISNsSwg81TClnjGtVV\n"
  56. "61cYOmGWgKbbnpvSOqbZWMHs9W4Lg2waNbGnQ3G+l7alWiMRV4qTjhkrdVRuvTxL\n"
  57. "OGOAfAhGB4Y5txDUNdTwuSp+GpuqcoYOmQWW4IIrjIOZMlamZQcIs7p/2CzfoLQH\n"
  58. "NuFuBeR+MLDMsMO7O42N+pcFWqPCplmRIkDWB2ru+DpJcaTtts/16f1/nf4KbMmp\n"
  59. "VlObWP/l48/XZjythzQir5AV6W13VM7MFToQqPxjy/c9F06/RjiW7sFv/r58pNsP\n"
  60. "k0iWcL0wBJ0GHZRGsCNOKMl08qowjynIVMKhIADYFXm84r69R1CO9KocixnqsH29\n"
  61. "uQIDAQAB\n"
  62. "-----END PUBLIC KEY-----\n";
  63. /* ============================================================= */
  64. using namespace cryptohelper;
  65. #ifdef _USE_OPENSSL
  66. class CryptoUnitTest : public CppUnit::TestFixture
  67. {
  68. public:
  69. CPPUNIT_TEST_SUITE(CryptoUnitTest);
  70. CPPUNIT_TEST(digiSignTests);
  71. CPPUNIT_TEST(pkeEncryptDecryptTest);
  72. CPPUNIT_TEST(pkeParallelTest);
  73. CPPUNIT_TEST(aesEncryptDecryptTests);
  74. CPPUNIT_TEST(aesWithRsaEncryptedKey);
  75. CPPUNIT_TEST(aesParallelTest);
  76. CPPUNIT_TEST_SUITE_END();
  77. protected:
  78. void asyncDigiSignUnitTest(IDigitalSignatureManager * _dsm)
  79. {
  80. class casyncfor: public CAsyncFor
  81. {
  82. IDigitalSignatureManager * dsm;
  83. public:
  84. casyncfor(IDigitalSignatureManager * _dsm)
  85. {
  86. dsm = _dsm;
  87. }
  88. void Do(unsigned idx)
  89. {
  90. VStringBuffer text("I am here %d", idx);
  91. StringBuffer sig;
  92. bool ok = dsm->digiSign(text, sig);
  93. if (!ok)
  94. printf("Asynchronous asyncDigiSignUnitTest() test %d failed!\n", idx);
  95. ASSERT(ok);
  96. }
  97. } afor(_dsm);
  98. printf("Executing 1000 asyncDigiSignUnitTest() operations\n");
  99. afor.For(1000,20,true,true);
  100. printf("Asynchronous asyncDigiSignUnitTest() test complete\n");
  101. }
  102. void asyncDigiVerifyUnitTest(IDigitalSignatureManager * _dsm)
  103. {
  104. class casyncfor: public CAsyncFor
  105. {
  106. IDigitalSignatureManager * dsm;
  107. StringBuffer text;
  108. StringBuffer sig;
  109. public:
  110. casyncfor(IDigitalSignatureManager * _dsm)
  111. {
  112. dsm = _dsm;
  113. text.set("I am here");
  114. bool ok = dsm->digiSign(text, sig);
  115. if (!ok)
  116. printf("Asynchronous asyncDigiVerifyUnitTest() failed in digiSign!\n");
  117. ASSERT(ok);
  118. }
  119. void Do(unsigned idx)
  120. {
  121. bool ok = dsm->digiVerify(text, sig);
  122. if (!ok)
  123. printf("Asynchronous asyncDigiVerifyUnitTest() test %d failed!\n", idx);
  124. ASSERT(ok);
  125. }
  126. } afor(_dsm);
  127. printf("Executing 1000 asyncDigiVerifyUnitTest() operations\n");
  128. afor.For(1000,20,true,true);
  129. printf("Asynchronous asyncDigiVerifyUnitTest() test complete\n");
  130. }
  131. void asyncDigiSignAndVerifyUnitTest(IDigitalSignatureManager * _dsm)
  132. {
  133. class casyncfor: public CAsyncFor
  134. {
  135. IDigitalSignatureManager * dsm;
  136. public:
  137. casyncfor(IDigitalSignatureManager * _dsm)
  138. {
  139. dsm = _dsm;
  140. }
  141. void Do(unsigned idx)
  142. {
  143. VStringBuffer text("I am here %d", idx);
  144. StringBuffer sig;
  145. bool ok = dsm->digiSign(text, sig);
  146. if (!ok)
  147. printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test %d failed!\n", idx);
  148. ASSERT(ok);
  149. ok = dsm->digiVerify(text, sig);
  150. if (!ok)
  151. printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test %d failed!\n", idx);
  152. ASSERT(ok);
  153. }
  154. } afor(_dsm);
  155. printf("Executing 1000 asynchronous asyncDigiSignAndVerifyUnitTest() operations\n");
  156. afor.For(1000,20,true,true);
  157. printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test complete\n");
  158. }
  159. void digiSignTests()
  160. {
  161. Owned<IException> exception;
  162. CppUnit::Exception *cppunitException;
  163. const char * text1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  164. const char * text2 = "~`!@#$%^&*()_-+=0123456789{[}]:;\"'<,>.?/'";
  165. const char * text3 = "W20180301-154415;ECLUsername";
  166. StringBuffer sig1;
  167. StringBuffer sig2;
  168. StringBuffer sig3;
  169. try
  170. {
  171. printf("\nExecuting digiSign() unit tests\n");
  172. //Create instance of digital signature manager
  173. StringBuffer _pubKeyBuff(pubKey);
  174. StringBuffer _privKeyBuff(privKey);
  175. Owned<IDigitalSignatureManager> dsm(createDigitalSignatureManagerInstanceFromKeys(_pubKeyBuff, _privKeyBuff, nullptr));
  176. printf("digiSign() test 1\n");
  177. StringBuffer txt(text1);
  178. bool ok = dsm->digiSign(text1, sig1.clear());
  179. ASSERT(ok);
  180. ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
  181. ASSERT(!sig1.isEmpty());//signature should be populated
  182. StringBuffer sig(sig1);
  183. ok = dsm->digiVerify(text1, sig1);
  184. ASSERT(ok);
  185. ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
  186. ASSERT(0 == strcmp(sig.str(), sig1.str()));//signature should be unchanged
  187. printf("digiSign() test 2\n");
  188. ok = dsm->digiVerify(text1, sig1);
  189. ASSERT(ok);
  190. ok = dsm->digiVerify(text1, sig1);
  191. ASSERT(ok);
  192. printf("digiSign() test 3\n");
  193. ok = dsm->digiSign(text2, sig2.clear());
  194. ASSERT(ok);
  195. ok = dsm->digiVerify(text2, sig2);
  196. ASSERT(ok);
  197. ok = dsm->digiSign(text2, sig2.clear());
  198. ASSERT(ok);
  199. ok = dsm->digiVerify(text2, sig2);
  200. ASSERT(ok);
  201. printf("digiSign() test 4\n");
  202. ok = dsm->digiVerify(text1, sig1);
  203. ASSERT(ok);
  204. printf("digiSign() test 5\n");
  205. ok = dsm->digiVerify(text2, sig2);
  206. ASSERT(ok);
  207. printf("digiSign() test 6\n");
  208. ok = dsm->digiVerify(text1, sig2);
  209. ASSERT(!ok);//should fail
  210. printf("digiSign() test 7\n");
  211. ok = dsm->digiVerify(text2, sig1);
  212. ASSERT(!ok);//should fail
  213. printf("digiSign() test 8\n");
  214. ok = dsm->digiSign(text3, sig3.clear());
  215. ASSERT(ok);
  216. printf("digiSign() test 9\n");
  217. ok = dsm->digiVerify(text3, sig1);
  218. ASSERT(!ok);//should fail
  219. ok = dsm->digiVerify(text3, sig2);
  220. ASSERT(!ok);//should fail
  221. ok = dsm->digiVerify(text3, sig3);
  222. ASSERT(ok);
  223. //Perform
  224. printf("digiSign() loop test\n");
  225. unsigned now = msTick();
  226. for (int x=0; x<1000; x++)
  227. {
  228. dsm->digiSign(text3, sig3.clear());
  229. }
  230. printf("digiSign() 1000 iterations took %d MS\n", msTick() - now);
  231. printf("digiVerify() loop test\n");
  232. now = msTick();
  233. for (int x=0; x<1000; x++)
  234. {
  235. dsm->digiVerify(text3, sig3);
  236. }
  237. printf("digiverify 1000 iterations took %d MS\n", msTick() - now);
  238. now = msTick();
  239. printf("\nAsynchronous test digiSign\n");
  240. asyncDigiSignUnitTest(dsm);
  241. printf("digiSign 1000 async iterations took %d MS\n", msTick() - now);
  242. now = msTick();
  243. printf("\nAsynchronous test digiVerify\n");
  244. asyncDigiVerifyUnitTest(dsm);
  245. printf("digiverify 1000 async iterations took %d MS\n", msTick() - now);
  246. now = msTick();
  247. printf("\nAsynchronous test digiSign and digiVerify\n");
  248. asyncDigiSignAndVerifyUnitTest(dsm);
  249. printf("digiSign/digiverify 1000 async iterations took %d MS\n", msTick() - now);
  250. }
  251. catch (IException *e)
  252. {
  253. StringBuffer err;
  254. e->errorMessage(err);
  255. printf("Digisign IException thrown:%s\n", err.str());
  256. exception.setown(e);
  257. }
  258. catch (CppUnit::Exception &e)
  259. {
  260. printf("Digisign CppUnit::Exception thrown\n");
  261. cppunitException = e.clone();
  262. }
  263. printf("Completed executing digiSign() unit tests\n");
  264. }
  265. void _pkeEncryptDecryptTest()
  266. {
  267. try
  268. {
  269. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  270. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  271. // create random data
  272. MemoryBuffer toEncryptMb;
  273. fillRandomData(245, toEncryptMb); // max for RSA
  274. MemoryBuffer pkeMb;
  275. publicKeyEncrypt(pkeMb, toEncryptMb.length(), toEncryptMb.bytes(), *publicKey);
  276. MemoryBuffer decryptedMb;
  277. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  278. ASSERT(toEncryptMb.length() == decryptedMb.length());
  279. ASSERT(0 == memcmp(toEncryptMb.bytes(), decryptedMb.bytes(), toEncryptMb.length()));
  280. }
  281. catch (IException *e)
  282. {
  283. StringBuffer err;
  284. e->errorMessage(err);
  285. printf("pkeEncryptDecryptTest IException thrown:%s\n", err.str());
  286. throw;
  287. }
  288. catch (CppUnit::Exception &e)
  289. {
  290. printf("pkeEncryptDecryptTest CppUnit::Exception thrown\n");
  291. throw;
  292. }
  293. }
  294. void pkeEncryptDecryptTest()
  295. {
  296. printf("\nExecuting pkeEncryptDecryptTest() unit tests\n");
  297. _pkeEncryptDecryptTest();
  298. }
  299. void pkeParallelTest()
  300. {
  301. class CAsyncfor : public CAsyncFor
  302. {
  303. std::function<void()> testFunc;
  304. public:
  305. CAsyncfor(std::function<void()> _testFunc) : testFunc(_testFunc)
  306. {
  307. }
  308. void Do(unsigned idx)
  309. {
  310. testFunc();
  311. }
  312. } afor(std::bind(&CryptoUnitTest::_pkeEncryptDecryptTest, this));
  313. printf("\nExecuting 1000 asynchronous pkeParallelTest() operations\n");
  314. CCycleTimer timer;
  315. afor.For(1000, 20, true, true);
  316. printf("Asynchronous pkeParallelTest() test completed in %u ms\n", timer.elapsedMs());
  317. }
  318. void aesEncryptDecryptTests()
  319. {
  320. try
  321. {
  322. printf("\nExecuting aesEncryptDecryptTests() unit tests\n");
  323. // create random data
  324. MemoryBuffer messageMb, encryptedMessageMb, decryptedMessageMb;
  325. char aesKey[aesMaxKeySize];
  326. char aesIV[aesBlockSize];
  327. fillRandomData(aesMaxKeySize, aesKey);
  328. fillRandomData(aesBlockSize, aesIV);
  329. fillRandomData(1024*100, messageMb);
  330. printf("aesEncryptDecryptTests with %u bytes with 256bit aes key\n", messageMb.length());
  331. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  332. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  333. ASSERT(messageMb.length() == decryptedMessageMb.length());
  334. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  335. printf("aesEncryptDecryptTests with %u bytes with 192bit aes key\n", messageMb.length());
  336. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), 192/8, aesKey, aesIV);
  337. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), 192/8, aesKey, aesIV);
  338. ASSERT(messageMb.length() == decryptedMessageMb.length());
  339. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  340. printf("aesEncryptDecryptTests with %u bytes with 128bit aes key\n", messageMb.length());
  341. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), 128/8, aesKey, aesIV);
  342. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), 128/8, aesKey, aesIV);
  343. ASSERT(messageMb.length() == decryptedMessageMb.length());
  344. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  345. messageMb.clear(); // 0 length test
  346. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  347. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  348. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  349. ASSERT(messageMb.length() == decryptedMessageMb.length());
  350. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  351. fillRandomData(1, messageMb.clear()); // 1 byte test
  352. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  353. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  354. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  355. ASSERT(messageMb.length() == decryptedMessageMb.length());
  356. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  357. fillRandomData(cryptohelper::aesBlockSize-1, messageMb.clear()); // aesBlockSize-1 test
  358. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  359. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  360. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  361. ASSERT(messageMb.length() == decryptedMessageMb.length());
  362. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  363. fillRandomData(cryptohelper::aesBlockSize, messageMb.clear()); // aesBlockSize test
  364. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  365. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  366. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  367. ASSERT(messageMb.length() == decryptedMessageMb.length());
  368. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  369. fillRandomData(cryptohelper::aesBlockSize+1, messageMb.clear()); // aesBlockSize+1 test
  370. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  371. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  372. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  373. ASSERT(messageMb.length() == decryptedMessageMb.length());
  374. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  375. }
  376. catch (IException *e)
  377. {
  378. StringBuffer err;
  379. e->errorMessage(err);
  380. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  381. throw;
  382. }
  383. catch (CppUnit::Exception &e)
  384. {
  385. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  386. throw;
  387. }
  388. }
  389. void aesWithRsaEncryptedKey()
  390. {
  391. try
  392. {
  393. printf("\nExecuting aesWithRsaEncryptedKey() unit tests\n");
  394. // create random data
  395. MemoryBuffer messageMb;
  396. fillRandomData(1024*100, messageMb);
  397. char aesKey[aesMaxKeySize];
  398. char aesIV[aesBlockSize];
  399. fillRandomData(aesMaxKeySize, aesKey);
  400. fillRandomData(aesBlockSize, aesIV);
  401. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  402. MemoryBuffer encryptedMessageMb;
  403. aesEncryptWithRSAEncryptedKey(encryptedMessageMb, messageMb.length(), messageMb.bytes(), *publicKey);
  404. // would normally be server side
  405. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  406. MemoryBuffer decryptedMessageMb;
  407. aesDecryptWithRSAEncryptedKey(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), *privateKey);
  408. ASSERT(messageMb.length() == decryptedMessageMb.length());
  409. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  410. }
  411. catch (IException *e)
  412. {
  413. StringBuffer err;
  414. e->errorMessage(err);
  415. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  416. throw;
  417. }
  418. catch (CppUnit::Exception &e)
  419. {
  420. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  421. throw;
  422. }
  423. }
  424. void aesParallelTest()
  425. {
  426. class CAsyncfor : public CAsyncFor
  427. {
  428. MemoryBuffer messageMb;
  429. char aesKey[aesMaxKeySize];
  430. char aesIV[aesBlockSize];
  431. public:
  432. CAsyncfor()
  433. {
  434. // create random key
  435. fillRandomData(aesMaxKeySize, aesKey);
  436. fillRandomData(aesBlockSize, aesIV);
  437. // create random data
  438. fillRandomData(1024*100, messageMb);
  439. }
  440. void Do(unsigned idx)
  441. {
  442. MemoryBuffer encryptedMessageMb;
  443. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  444. MemoryBuffer decryptedMessageMb;
  445. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  446. ASSERT(messageMb.length() == decryptedMessageMb.length());
  447. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  448. }
  449. } afor;
  450. printf("\nExecuting 1000 asynchronous aesParallelTest() operations\n");
  451. CCycleTimer timer;
  452. afor.For(1000, 20, true, true);
  453. printf("Asynchronous aesParallelTest() test completed in %u ms\n", timer.elapsedMs());
  454. }
  455. };
  456. class CryptoTestTiming : public CppUnit::TestFixture
  457. {
  458. size32_t dataSz = 0x100000 * 10; // 10MB
  459. public:
  460. CPPUNIT_TEST_SUITE(CryptoTestTiming);
  461. CPPUNIT_TEST(aesSpeedTest);
  462. CPPUNIT_TEST(rsaSpeedTest);
  463. CPPUNIT_TEST(rsaKeyLoadSpeedTest);
  464. CPPUNIT_TEST(aesCompareJlibVsCryptoHelper);
  465. CPPUNIT_TEST_SUITE_END();
  466. void aesCompareJlibVsCryptoHelper()
  467. {
  468. MemoryBuffer messageMb, encryptedMessageMb, decryptedMessageMb;
  469. char aesKey[aesMaxKeySize];
  470. char aesIV[aesBlockSize];
  471. // create random key
  472. fillRandomData(aesMaxKeySize, aesKey);
  473. fillRandomData(aesBlockSize, aesIV);
  474. // create random data
  475. fillRandomData(dataSz, messageMb);
  476. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  477. CCycleTimer timer;
  478. cryptohelper::aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  479. printf("OPENSSL AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  480. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  481. timer.reset();
  482. cryptohelper::aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  483. printf("OPENSSL AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  484. ASSERT(messageMb.length() == decryptedMessageMb.length());
  485. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  486. encryptedMessageMb.clear();
  487. timer.reset();
  488. ::aesEncrypt(aesKey, aesMaxKeySize, messageMb.bytes(), messageMb.length(), encryptedMessageMb);
  489. printf("JLIB AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  490. decryptedMessageMb.clear();
  491. timer.reset();
  492. ::aesDecrypt(aesKey, aesMaxKeySize, encryptedMessageMb.bytes(), encryptedMessageMb.length(), decryptedMessageMb);
  493. printf("JLIB AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  494. ASSERT(messageMb.length() == decryptedMessageMb.length());
  495. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  496. }
  497. void aesSpeedTest()
  498. {
  499. MemoryBuffer messageMb;
  500. char aesKey[aesMaxKeySize];
  501. char aesIV[aesBlockSize];
  502. // create random key
  503. fillRandomData(aesMaxKeySize, aesKey);
  504. fillRandomData(aesBlockSize, aesIV);
  505. // create random data
  506. fillRandomData(dataSz, messageMb);
  507. MemoryBuffer encryptedMessageMb;
  508. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  509. CCycleTimer timer;
  510. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  511. printf("AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  512. MemoryBuffer decryptedMessageMb;
  513. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  514. timer.reset();
  515. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  516. printf("AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  517. }
  518. void rsaSpeedTest()
  519. {
  520. // create random data
  521. MemoryBuffer messageMb;
  522. fillRandomData(dataSz, messageMb);
  523. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  524. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  525. MemoryBuffer encryptedMessageMb;
  526. MemoryBuffer decryptedMessageMb;
  527. // pre-alloc memory, so as not part of the timing
  528. size32_t maxPerEncryptSz = 245;
  529. unsigned numPackets = ((dataSz + (maxPerEncryptSz-1)) / maxPerEncryptSz);
  530. size32_t dstMaxSz = numPackets * 256; // approx
  531. encryptedMessageMb.ensureCapacity(dstMaxSz);
  532. const byte *src = messageMb.bytes();
  533. byte *dst = (byte *)encryptedMessageMb.bufferBase();
  534. size32_t remaining = dataSz;
  535. size32_t encryptPacketSz = 256;
  536. CCycleTimer timer;
  537. while (true)
  538. {
  539. size32_t cp = remaining>maxPerEncryptSz ? maxPerEncryptSz : remaining;
  540. size_t eSz = publicKeyEncrypt(dst, dstMaxSz, cp, src, *publicKey);
  541. assertex(eSz);
  542. assertex(eSz == encryptPacketSz); //consistent for size being encrypted, assumed on decrypt
  543. src += cp;
  544. remaining -= cp;
  545. dst += eSz;
  546. dstMaxSz -= eSz;
  547. if (0 == remaining)
  548. break;
  549. }
  550. encryptedMessageMb.rewrite(dst-(byte*)encryptedMessageMb.bufferBase());
  551. printf("RSA %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  552. size32_t encryptedDataSz = encryptedMessageMb.length();
  553. remaining = encryptedDataSz;
  554. src = encryptedMessageMb.bytes();
  555. dstMaxSz = ((numPackets-1) * maxPerEncryptSz) + encryptPacketSz; // because encrypt always needs buffer to have enough room for encryptPacketSz
  556. decryptedMessageMb.ensureCapacity(dstMaxSz);
  557. dst = (byte *)decryptedMessageMb.bufferBase();
  558. timer.reset();
  559. while (true)
  560. {
  561. size_t eSz = privateKeyDecrypt(dst, dstMaxSz, encryptPacketSz, src, *privateKey);
  562. assertex(eSz);
  563. assertex(eSz <= maxPerEncryptSz);
  564. src += encryptPacketSz;
  565. remaining -= encryptPacketSz;
  566. dst += eSz;
  567. dstMaxSz -= eSz;
  568. if (0 == remaining)
  569. break;
  570. }
  571. printf("RSA %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  572. }
  573. void rsaKeyLoadSpeedTest()
  574. {
  575. // create random data
  576. size32_t dataSz = 245;
  577. MemoryBuffer messageMb;
  578. fillRandomData(dataSz, messageMb);
  579. unsigned numCycles = 1000;
  580. CCycleTimer timer;
  581. for (unsigned i=0; i<numCycles; i++)
  582. {
  583. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  584. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  585. MemoryBuffer pkeMb;
  586. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  587. MemoryBuffer decryptedMb;
  588. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  589. }
  590. printf("RSA %u cycles - reloading keys each iteration - %u ms\n", numCycles, timer.elapsedMs());
  591. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  592. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  593. timer.reset();
  594. for (unsigned i=0; i<numCycles; i++)
  595. {
  596. MemoryBuffer pkeMb;
  597. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  598. MemoryBuffer decryptedMb;
  599. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  600. }
  601. printf("RSA %u cycles - reusing loaded keys - %u ms\n", numCycles, timer.elapsedMs());
  602. }
  603. };
  604. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoUnitTest );
  605. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoUnitTest, "CryptoUnitTest" );
  606. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoTestTiming );
  607. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoTestTiming, "CryptoTestTiming" );
  608. #endif
  609. #endif // _USE_CPPUNIT