cryptotests.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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[aesKeySize];
  326. char aesIV[aesBlockSize];
  327. fillRandomData(aesKeySize, aesKey);
  328. fillRandomData(aesBlockSize, aesIV);
  329. fillRandomData(1024*100, messageMb);
  330. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  331. aesKeyEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  332. aesKeyDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  333. ASSERT(messageMb.length() == decryptedMessageMb.length());
  334. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  335. messageMb.clear(); // 0 length test
  336. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  337. aesKeyEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  338. aesKeyDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  339. ASSERT(messageMb.length() == decryptedMessageMb.length());
  340. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  341. fillRandomData(1, messageMb.clear()); // 1 byte test
  342. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  343. aesKeyEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  344. aesKeyDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  345. ASSERT(messageMb.length() == decryptedMessageMb.length());
  346. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  347. fillRandomData(cryptohelper::aesBlockSize-1, messageMb.clear()); // aesBlockSize-1 test
  348. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  349. aesKeyEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  350. aesKeyDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  351. ASSERT(messageMb.length() == decryptedMessageMb.length());
  352. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  353. fillRandomData(cryptohelper::aesBlockSize, messageMb.clear()); // aesBlockSize test
  354. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  355. aesKeyEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  356. aesKeyDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  357. ASSERT(messageMb.length() == decryptedMessageMb.length());
  358. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  359. fillRandomData(cryptohelper::aesBlockSize+1, messageMb.clear()); // aesBlockSize+1 test
  360. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  361. aesKeyEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  362. aesKeyDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  363. ASSERT(messageMb.length() == decryptedMessageMb.length());
  364. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  365. }
  366. catch (IException *e)
  367. {
  368. StringBuffer err;
  369. e->errorMessage(err);
  370. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  371. throw;
  372. }
  373. catch (CppUnit::Exception &e)
  374. {
  375. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  376. throw;
  377. }
  378. }
  379. void aesWithRsaEncryptedKey()
  380. {
  381. try
  382. {
  383. printf("\nExecuting aesWithRsaEncryptedKey() unit tests\n");
  384. // create random data
  385. MemoryBuffer messageMb;
  386. fillRandomData(1024*100, messageMb);
  387. char aesKey[aesKeySize];
  388. char aesIV[aesBlockSize];
  389. fillRandomData(aesKeySize, aesKey);
  390. fillRandomData(aesBlockSize, aesIV);
  391. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  392. MemoryBuffer encryptedMessageMb;
  393. aesEncryptWithRSAEncryptedKey(encryptedMessageMb, messageMb.length(), messageMb.bytes(), *publicKey);
  394. // would normally be server side
  395. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  396. MemoryBuffer decryptedMessageMb;
  397. aesDecryptWithRSAEncryptedKey(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), *privateKey);
  398. ASSERT(messageMb.length() == decryptedMessageMb.length());
  399. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  400. }
  401. catch (IException *e)
  402. {
  403. StringBuffer err;
  404. e->errorMessage(err);
  405. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  406. throw;
  407. }
  408. catch (CppUnit::Exception &e)
  409. {
  410. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  411. throw;
  412. }
  413. }
  414. void aesParallelTest()
  415. {
  416. class CAsyncfor : public CAsyncFor
  417. {
  418. MemoryBuffer messageMb;
  419. char aesKey[aesKeySize];
  420. char aesIV[aesBlockSize];
  421. public:
  422. CAsyncfor()
  423. {
  424. // create random key
  425. fillRandomData(aesKeySize, aesKey);
  426. fillRandomData(aesBlockSize, aesIV);
  427. // create random data
  428. fillRandomData(1024*100, messageMb);
  429. }
  430. void Do(unsigned idx)
  431. {
  432. MemoryBuffer encryptedMessageMb;
  433. aesKeyEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  434. MemoryBuffer decryptedMessageMb;
  435. aesKeyDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  436. ASSERT(messageMb.length() == decryptedMessageMb.length());
  437. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  438. }
  439. } afor;
  440. printf("\nExecuting 1000 asynchronous aesParallelTest() operations\n");
  441. CCycleTimer timer;
  442. afor.For(1000, 20, true, true);
  443. printf("Asynchronous aesParallelTest() test completed in %u ms\n", timer.elapsedMs());
  444. }
  445. };
  446. class CryptoTestTiming : public CppUnit::TestFixture
  447. {
  448. size32_t dataSz = 0x100000 * 10; // 10MB
  449. public:
  450. CPPUNIT_TEST_SUITE(CryptoTestTiming);
  451. CPPUNIT_TEST(aesSpeedTest);
  452. CPPUNIT_TEST(rsaSpeedTest);
  453. CPPUNIT_TEST(rsaKeyLoadSpeedTest);
  454. CPPUNIT_TEST(aesCompareJlibVsCryptoHelper);
  455. CPPUNIT_TEST_SUITE_END();
  456. void aesCompareJlibVsCryptoHelper()
  457. {
  458. MemoryBuffer messageMb, encryptedMessageMb, decryptedMessageMb;
  459. char aesKey[aesKeySize];
  460. char aesIV[aesBlockSize];
  461. // create random key
  462. fillRandomData(aesKeySize, aesKey);
  463. fillRandomData(aesBlockSize, aesIV);
  464. // create random data
  465. fillRandomData(dataSz, messageMb);
  466. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  467. CCycleTimer timer;
  468. aesKeyEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  469. printf("OPENSSL AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  470. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  471. timer.reset();
  472. aesKeyDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  473. printf("OPENSSL AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  474. ASSERT(messageMb.length() == decryptedMessageMb.length());
  475. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  476. encryptedMessageMb.clear();
  477. timer.reset();
  478. aesEncrypt(aesKey, aesKeySize, messageMb.bytes(), messageMb.length(), encryptedMessageMb);
  479. printf("JLIB AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  480. decryptedMessageMb.clear();
  481. timer.reset();
  482. aesDecrypt(aesKey, aesKeySize, encryptedMessageMb.bytes(), encryptedMessageMb.length(), decryptedMessageMb);
  483. printf("JLIB 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. }
  487. void aesSpeedTest()
  488. {
  489. MemoryBuffer messageMb;
  490. char aesKey[aesKeySize];
  491. char aesIV[aesBlockSize];
  492. // create random key
  493. fillRandomData(aesKeySize, aesKey);
  494. fillRandomData(aesBlockSize, aesIV);
  495. // create random data
  496. fillRandomData(dataSz, messageMb);
  497. MemoryBuffer encryptedMessageMb;
  498. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  499. CCycleTimer timer;
  500. aesKeyEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesKey, aesIV);
  501. printf("AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  502. MemoryBuffer decryptedMessageMb;
  503. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  504. timer.reset();
  505. aesKeyDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesKey, aesIV);
  506. printf("AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  507. }
  508. void rsaSpeedTest()
  509. {
  510. // create random data
  511. MemoryBuffer messageMb;
  512. fillRandomData(dataSz, messageMb);
  513. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  514. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  515. MemoryBuffer encryptedMessageMb;
  516. MemoryBuffer decryptedMessageMb;
  517. // pre-alloc memory, so as not part of the timing
  518. size32_t maxPerEncryptSz = 245;
  519. unsigned numPackets = ((dataSz + (maxPerEncryptSz-1)) / maxPerEncryptSz);
  520. size32_t dstMaxSz = numPackets * 256; // approx
  521. encryptedMessageMb.ensureCapacity(dstMaxSz);
  522. const byte *src = messageMb.bytes();
  523. byte *dst = (byte *)encryptedMessageMb.bufferBase();
  524. size32_t remaining = dataSz;
  525. size32_t encryptPacketSz = 256;
  526. CCycleTimer timer;
  527. while (true)
  528. {
  529. size32_t cp = remaining>maxPerEncryptSz ? maxPerEncryptSz : remaining;
  530. size_t eSz = publicKeyEncrypt(dst, dstMaxSz, cp, src, *publicKey);
  531. assertex(eSz);
  532. assertex(eSz == encryptPacketSz); //consistent for size being encrypted, assumed on decrypt
  533. src += cp;
  534. remaining -= cp;
  535. dst += eSz;
  536. dstMaxSz -= eSz;
  537. if (0 == remaining)
  538. break;
  539. }
  540. encryptedMessageMb.rewrite(dst-(byte*)encryptedMessageMb.bufferBase());
  541. printf("RSA %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  542. size32_t encryptedDataSz = encryptedMessageMb.length();
  543. remaining = encryptedDataSz;
  544. src = encryptedMessageMb.bytes();
  545. dstMaxSz = ((numPackets-1) * maxPerEncryptSz) + encryptPacketSz; // because encrypt always needs buffer to have enough room for encryptPacketSz
  546. decryptedMessageMb.ensureCapacity(dstMaxSz);
  547. dst = (byte *)decryptedMessageMb.bufferBase();
  548. timer.reset();
  549. while (true)
  550. {
  551. size_t eSz = privateKeyDecrypt(dst, dstMaxSz, encryptPacketSz, src, *privateKey);
  552. assertex(eSz);
  553. assertex(eSz <= maxPerEncryptSz);
  554. src += encryptPacketSz;
  555. remaining -= encryptPacketSz;
  556. dst += eSz;
  557. dstMaxSz -= eSz;
  558. if (0 == remaining)
  559. break;
  560. }
  561. printf("RSA %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  562. }
  563. void rsaKeyLoadSpeedTest()
  564. {
  565. // create random data
  566. size32_t dataSz = 245;
  567. MemoryBuffer messageMb;
  568. fillRandomData(dataSz, messageMb);
  569. unsigned numCycles = 1000;
  570. CCycleTimer timer;
  571. for (unsigned i=0; i<numCycles; i++)
  572. {
  573. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  574. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  575. MemoryBuffer pkeMb;
  576. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  577. MemoryBuffer decryptedMb;
  578. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  579. }
  580. printf("RSA %u cycles - reloading keys each iteration - %u ms\n", numCycles, timer.elapsedMs());
  581. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  582. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  583. timer.reset();
  584. for (unsigned i=0; i<numCycles; i++)
  585. {
  586. MemoryBuffer pkeMb;
  587. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  588. MemoryBuffer decryptedMb;
  589. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  590. }
  591. printf("RSA %u cycles - reusing loaded keys - %u ms\n", numCycles, timer.elapsedMs());
  592. }
  593. };
  594. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoUnitTest );
  595. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoUnitTest, "CryptoUnitTest" );
  596. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoTestTiming );
  597. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoTestTiming, "CryptoTestTiming" );
  598. #endif
  599. #endif // _USE_CPPUNIT