cryptotests.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  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(sig, text);
  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(sig, text);
  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(sig, text);
  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. Owned<IDigitalSignatureManager> dsm(createDigitalSignatureManagerInstanceFromKeys(pubKey, privKey, nullptr));
  174. printf("digiSign() test 1\n");
  175. StringBuffer txt(text1);
  176. bool ok = dsm->digiSign(sig1.clear(), text1);
  177. ASSERT(ok);
  178. ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
  179. ASSERT(!sig1.isEmpty());//signature should be populated
  180. StringBuffer sig(sig1);
  181. ok = dsm->digiVerify(sig1, text1);
  182. ASSERT(ok);
  183. ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
  184. ASSERT(0 == strcmp(sig.str(), sig1.str()));//signature should be unchanged
  185. printf("digiSign() test 2\n");
  186. ok = dsm->digiVerify(sig1, text1);
  187. ASSERT(ok);
  188. ok = dsm->digiVerify(sig1, text1);
  189. ASSERT(ok);
  190. printf("digiSign() test 3\n");
  191. ok = dsm->digiSign(sig2.clear(), text2);
  192. ASSERT(ok);
  193. ok = dsm->digiVerify(sig2, text2);
  194. ASSERT(ok);
  195. ok = dsm->digiSign(sig2.clear(), text2);
  196. ASSERT(ok);
  197. ok = dsm->digiVerify(sig2, text2);
  198. ASSERT(ok);
  199. printf("digiSign() test 4\n");
  200. ok = dsm->digiVerify(sig1, text1);
  201. ASSERT(ok);
  202. printf("digiSign() test 5\n");
  203. ok = dsm->digiVerify(sig2, text2);
  204. ASSERT(ok);
  205. printf("digiSign() test 6\n");
  206. ok = dsm->digiVerify(sig2, text1);
  207. ASSERT(!ok);//should fail
  208. printf("digiSign() test 7\n");
  209. ok = dsm->digiVerify(sig1, text2);
  210. ASSERT(!ok);//should fail
  211. printf("digiSign() test 8\n");
  212. ok = dsm->digiSign(sig3.clear(), text3);
  213. ASSERT(ok);
  214. printf("digiSign() test 9\n");
  215. ok = dsm->digiVerify(sig1, text3);
  216. ASSERT(!ok);//should fail
  217. ok = dsm->digiVerify(sig2, text3);
  218. ASSERT(!ok);//should fail
  219. ok = dsm->digiVerify(sig3, text3);
  220. ASSERT(ok);
  221. //Perform
  222. printf("digiSign() loop test\n");
  223. unsigned now = msTick();
  224. for (int x=0; x<1000; x++)
  225. {
  226. dsm->digiSign(sig3.clear(), text3);
  227. }
  228. printf("digiSign() 1000 iterations took %d MS\n", msTick() - now);
  229. printf("digiVerify() loop test\n");
  230. now = msTick();
  231. for (int x=0; x<1000; x++)
  232. {
  233. dsm->digiVerify(sig3, text3);
  234. }
  235. printf("digiverify 1000 iterations took %d MS\n", msTick() - now);
  236. now = msTick();
  237. printf("\nAsynchronous test digiSign\n");
  238. asyncDigiSignUnitTest(dsm);
  239. printf("digiSign 1000 async iterations took %d MS\n", msTick() - now);
  240. now = msTick();
  241. printf("\nAsynchronous test digiVerify\n");
  242. asyncDigiVerifyUnitTest(dsm);
  243. printf("digiverify 1000 async iterations took %d MS\n", msTick() - now);
  244. now = msTick();
  245. printf("\nAsynchronous test digiSign and digiVerify\n");
  246. asyncDigiSignAndVerifyUnitTest(dsm);
  247. printf("digiSign/digiverify 1000 async iterations took %d MS\n", msTick() - now);
  248. }
  249. catch (IException *e)
  250. {
  251. StringBuffer err;
  252. e->errorMessage(err);
  253. printf("Digisign IException thrown:%s\n", err.str());
  254. exception.setown(e);
  255. }
  256. catch (CppUnit::Exception &e)
  257. {
  258. printf("Digisign CppUnit::Exception thrown\n");
  259. cppunitException = e.clone();
  260. }
  261. printf("Completed executing digiSign() unit tests\n");
  262. }
  263. void _pkeEncryptDecryptTest()
  264. {
  265. try
  266. {
  267. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  268. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  269. // create random data
  270. MemoryBuffer toEncryptMb;
  271. fillRandomData(245, toEncryptMb); // max for RSA
  272. MemoryBuffer pkeMb;
  273. publicKeyEncrypt(pkeMb, toEncryptMb.length(), toEncryptMb.bytes(), *publicKey);
  274. MemoryBuffer decryptedMb;
  275. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  276. ASSERT(toEncryptMb.length() == decryptedMb.length());
  277. ASSERT(0 == memcmp(toEncryptMb.bytes(), decryptedMb.bytes(), toEncryptMb.length()));
  278. }
  279. catch (IException *e)
  280. {
  281. StringBuffer err;
  282. e->errorMessage(err);
  283. printf("pkeEncryptDecryptTest IException thrown:%s\n", err.str());
  284. throw;
  285. }
  286. catch (CppUnit::Exception &e)
  287. {
  288. printf("pkeEncryptDecryptTest CppUnit::Exception thrown\n");
  289. throw;
  290. }
  291. }
  292. void pkeEncryptDecryptTest()
  293. {
  294. printf("\nExecuting pkeEncryptDecryptTest() unit tests\n");
  295. _pkeEncryptDecryptTest();
  296. }
  297. void pkeParallelTest()
  298. {
  299. class CAsyncfor : public CAsyncFor
  300. {
  301. std::function<void()> testFunc;
  302. public:
  303. CAsyncfor(std::function<void()> _testFunc) : testFunc(_testFunc)
  304. {
  305. }
  306. void Do(unsigned idx)
  307. {
  308. testFunc();
  309. }
  310. } afor(std::bind(&CryptoUnitTest::_pkeEncryptDecryptTest, this));
  311. printf("\nExecuting 1000 asynchronous pkeParallelTest() operations\n");
  312. CCycleTimer timer;
  313. afor.For(1000, 20, true, true);
  314. printf("Asynchronous pkeParallelTest() test completed in %u ms\n", timer.elapsedMs());
  315. }
  316. void aesEncryptDecryptTests()
  317. {
  318. try
  319. {
  320. printf("\nExecuting aesEncryptDecryptTests() unit tests\n");
  321. // create random data
  322. MemoryBuffer messageMb, encryptedMessageMb, decryptedMessageMb;
  323. char aesKey[aesMaxKeySize];
  324. char aesIV[aesBlockSize];
  325. fillRandomData(aesMaxKeySize, aesKey);
  326. fillRandomData(aesBlockSize, aesIV);
  327. fillRandomData(1024*100, messageMb);
  328. printf("aesEncryptDecryptTests with %u bytes with 256bit aes key\n", messageMb.length());
  329. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  330. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  331. ASSERT(messageMb.length() == decryptedMessageMb.length());
  332. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  333. printf("aesEncryptDecryptTests with %u bytes with 192bit aes key\n", messageMb.length());
  334. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), 192/8, aesKey, aesIV);
  335. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), 192/8, aesKey, aesIV);
  336. ASSERT(messageMb.length() == decryptedMessageMb.length());
  337. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  338. printf("aesEncryptDecryptTests with %u bytes with 128bit aes key\n", messageMb.length());
  339. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), 128/8, aesKey, aesIV);
  340. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), 128/8, aesKey, aesIV);
  341. ASSERT(messageMb.length() == decryptedMessageMb.length());
  342. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  343. messageMb.clear(); // 0 length test
  344. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  345. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  346. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  347. ASSERT(messageMb.length() == decryptedMessageMb.length());
  348. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  349. fillRandomData(1, messageMb.clear()); // 1 byte test
  350. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  351. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  352. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  353. ASSERT(messageMb.length() == decryptedMessageMb.length());
  354. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  355. fillRandomData(cryptohelper::aesBlockSize-1, messageMb.clear()); // aesBlockSize-1 test
  356. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  357. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  358. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  359. ASSERT(messageMb.length() == decryptedMessageMb.length());
  360. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  361. fillRandomData(cryptohelper::aesBlockSize, messageMb.clear()); // aesBlockSize test
  362. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  363. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  364. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  365. ASSERT(messageMb.length() == decryptedMessageMb.length());
  366. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  367. fillRandomData(cryptohelper::aesBlockSize+1, messageMb.clear()); // aesBlockSize+1 test
  368. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  369. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  370. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  371. ASSERT(messageMb.length() == decryptedMessageMb.length());
  372. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  373. }
  374. catch (IException *e)
  375. {
  376. StringBuffer err;
  377. e->errorMessage(err);
  378. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  379. throw;
  380. }
  381. catch (CppUnit::Exception &e)
  382. {
  383. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  384. throw;
  385. }
  386. }
  387. void aesWithRsaEncryptedKey()
  388. {
  389. try
  390. {
  391. printf("\nExecuting aesWithRsaEncryptedKey() unit tests\n");
  392. // create random data
  393. MemoryBuffer messageMb;
  394. fillRandomData(1024*100, messageMb);
  395. char aesKey[aesMaxKeySize];
  396. char aesIV[aesBlockSize];
  397. fillRandomData(aesMaxKeySize, aesKey);
  398. fillRandomData(aesBlockSize, aesIV);
  399. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  400. MemoryBuffer encryptedMessageMb;
  401. aesEncryptWithRSAEncryptedKey(encryptedMessageMb, messageMb.length(), messageMb.bytes(), *publicKey);
  402. // would normally be server side
  403. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  404. MemoryBuffer decryptedMessageMb;
  405. aesDecryptWithRSAEncryptedKey(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), *privateKey);
  406. ASSERT(messageMb.length() == decryptedMessageMb.length());
  407. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  408. }
  409. catch (IException *e)
  410. {
  411. StringBuffer err;
  412. e->errorMessage(err);
  413. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  414. throw;
  415. }
  416. catch (CppUnit::Exception &e)
  417. {
  418. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  419. throw;
  420. }
  421. }
  422. void aesParallelTest()
  423. {
  424. class CAsyncfor : public CAsyncFor
  425. {
  426. MemoryBuffer messageMb;
  427. char aesKey[aesMaxKeySize];
  428. char aesIV[aesBlockSize];
  429. public:
  430. CAsyncfor()
  431. {
  432. // create random key
  433. fillRandomData(aesMaxKeySize, aesKey);
  434. fillRandomData(aesBlockSize, aesIV);
  435. // create random data
  436. fillRandomData(1024*100, messageMb);
  437. }
  438. void Do(unsigned idx)
  439. {
  440. MemoryBuffer encryptedMessageMb;
  441. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  442. MemoryBuffer decryptedMessageMb;
  443. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  444. ASSERT(messageMb.length() == decryptedMessageMb.length());
  445. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  446. }
  447. } afor;
  448. printf("\nExecuting 1000 asynchronous aesParallelTest() operations\n");
  449. CCycleTimer timer;
  450. afor.For(1000, 20, true, true);
  451. printf("Asynchronous aesParallelTest() test completed in %u ms\n", timer.elapsedMs());
  452. }
  453. };
  454. class CryptoTestTiming : public CppUnit::TestFixture
  455. {
  456. size32_t dataSz = 0x100000 * 10; // 10MB
  457. public:
  458. CPPUNIT_TEST_SUITE(CryptoTestTiming);
  459. CPPUNIT_TEST(aesSpeedTest);
  460. CPPUNIT_TEST(rsaSpeedTest);
  461. CPPUNIT_TEST(rsaKeyLoadSpeedTest);
  462. CPPUNIT_TEST(aesCompareJlibVsCryptoHelper);
  463. CPPUNIT_TEST_SUITE_END();
  464. void aesCompareJlibVsCryptoHelper()
  465. {
  466. MemoryBuffer messageMb, encryptedMessageMb, decryptedMessageMb;
  467. char aesKey[aesMaxKeySize];
  468. char aesIV[aesBlockSize];
  469. // create random key
  470. fillRandomData(aesMaxKeySize, aesKey);
  471. fillRandomData(aesBlockSize, aesIV);
  472. // create random data
  473. fillRandomData(dataSz, messageMb);
  474. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  475. CCycleTimer timer;
  476. cryptohelper::aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  477. printf("OPENSSL AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  478. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  479. timer.reset();
  480. cryptohelper::aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  481. printf("OPENSSL AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  482. ASSERT(messageMb.length() == decryptedMessageMb.length());
  483. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  484. encryptedMessageMb.clear();
  485. timer.reset();
  486. jlib::aesEncrypt(aesKey, aesMaxKeySize, messageMb.bytes(), messageMb.length(), encryptedMessageMb);
  487. printf("JLIB AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  488. decryptedMessageMb.clear();
  489. timer.reset();
  490. jlib::aesDecrypt(aesKey, aesMaxKeySize, encryptedMessageMb.bytes(), encryptedMessageMb.length(), decryptedMessageMb);
  491. printf("JLIB AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  492. ASSERT(messageMb.length() == decryptedMessageMb.length());
  493. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  494. }
  495. void aesSpeedTest()
  496. {
  497. MemoryBuffer messageMb;
  498. char aesKey[aesMaxKeySize];
  499. char aesIV[aesBlockSize];
  500. // create random key
  501. fillRandomData(aesMaxKeySize, aesKey);
  502. fillRandomData(aesBlockSize, aesIV);
  503. // create random data
  504. fillRandomData(dataSz, messageMb);
  505. MemoryBuffer encryptedMessageMb;
  506. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  507. CCycleTimer timer;
  508. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  509. printf("AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  510. MemoryBuffer decryptedMessageMb;
  511. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  512. timer.reset();
  513. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  514. printf("AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  515. }
  516. void rsaSpeedTest()
  517. {
  518. // create random data
  519. MemoryBuffer messageMb;
  520. fillRandomData(dataSz, messageMb);
  521. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  522. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  523. MemoryBuffer encryptedMessageMb;
  524. MemoryBuffer decryptedMessageMb;
  525. // pre-alloc memory, so as not part of the timing
  526. size32_t maxPerEncryptSz = 245;
  527. unsigned numPackets = ((dataSz + (maxPerEncryptSz-1)) / maxPerEncryptSz);
  528. size32_t dstMaxSz = numPackets * 256; // approx
  529. encryptedMessageMb.ensureCapacity(dstMaxSz);
  530. const byte *src = messageMb.bytes();
  531. byte *dst = (byte *)encryptedMessageMb.bufferBase();
  532. size32_t remaining = dataSz;
  533. size32_t encryptPacketSz = 256;
  534. CCycleTimer timer;
  535. while (true)
  536. {
  537. size32_t cp = remaining>maxPerEncryptSz ? maxPerEncryptSz : remaining;
  538. size_t eSz = publicKeyEncrypt(dst, dstMaxSz, cp, src, *publicKey);
  539. assertex(eSz);
  540. assertex(eSz == encryptPacketSz); //consistent for size being encrypted, assumed on decrypt
  541. src += cp;
  542. remaining -= cp;
  543. dst += eSz;
  544. dstMaxSz -= eSz;
  545. if (0 == remaining)
  546. break;
  547. }
  548. encryptedMessageMb.rewrite(dst-(byte*)encryptedMessageMb.bufferBase());
  549. printf("RSA %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  550. size32_t encryptedDataSz = encryptedMessageMb.length();
  551. remaining = encryptedDataSz;
  552. src = encryptedMessageMb.bytes();
  553. dstMaxSz = ((numPackets-1) * maxPerEncryptSz) + encryptPacketSz; // because encrypt always needs buffer to have enough room for encryptPacketSz
  554. decryptedMessageMb.ensureCapacity(dstMaxSz);
  555. dst = (byte *)decryptedMessageMb.bufferBase();
  556. timer.reset();
  557. while (true)
  558. {
  559. size_t eSz = privateKeyDecrypt(dst, dstMaxSz, encryptPacketSz, src, *privateKey);
  560. assertex(eSz);
  561. assertex(eSz <= maxPerEncryptSz);
  562. src += encryptPacketSz;
  563. remaining -= encryptPacketSz;
  564. dst += eSz;
  565. dstMaxSz -= eSz;
  566. if (0 == remaining)
  567. break;
  568. }
  569. printf("RSA %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  570. }
  571. void rsaKeyLoadSpeedTest()
  572. {
  573. // create random data
  574. size32_t dataSz = 245;
  575. MemoryBuffer messageMb;
  576. fillRandomData(dataSz, messageMb);
  577. unsigned numCycles = 1000;
  578. CCycleTimer timer;
  579. for (unsigned i=0; i<numCycles; i++)
  580. {
  581. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  582. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  583. MemoryBuffer pkeMb;
  584. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  585. MemoryBuffer decryptedMb;
  586. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  587. }
  588. printf("RSA %u cycles - reloading keys each iteration - %u ms\n", numCycles, timer.elapsedMs());
  589. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey, nullptr);
  590. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  591. timer.reset();
  592. for (unsigned i=0; i<numCycles; i++)
  593. {
  594. MemoryBuffer pkeMb;
  595. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  596. MemoryBuffer decryptedMb;
  597. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  598. }
  599. printf("RSA %u cycles - reusing loaded keys - %u ms\n", numCycles, timer.elapsedMs());
  600. }
  601. };
  602. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoUnitTest );
  603. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoUnitTest, "CryptoUnitTest" );
  604. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoTestTiming );
  605. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoTestTiming, "CryptoTestTiming" );
  606. #endif
  607. #endif // _USE_CPPUNIT