cryptotests.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  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. /*Private key, with a passphrase, using
  65. openssl genrsa -aes128 -passout pass:ThisIsMyPassphrase -out priv.pem 1024
  66. */
  67. const char * privKeyPassphrase =
  68. "-----BEGIN RSA PRIVATE KEY-----\n"
  69. "Proc-Type: 4,ENCRYPTED\n"
  70. "DEK-Info: AES-128-CBC,27840180591F7545A3BC6AC26017B5E2\n"
  71. "\n"
  72. "JZ7kSTs0chmd3TmPTWQW3NM9dtfgJN59cecq8UzNeDfNdXQYU5WwhPFebpqX6K4H\n"
  73. "hRJ4pKaFCS39+ib68Yalwb5T+vru9t6WHhJkbGcl41bz6U0aXs3FCEEGFUEngVWu\n"
  74. "lonE8YjbeC+kiE7UlnGiFweteTJNlzbsFfa0w3U/6/tkfbd6ZDbriEhUvrbp1EPw\n"
  75. "JAAZDs9MNCqs2S76VqqWHyWhVI32lgauVRqDNZTZDSnXF9/huUUSuK8fLK4G68Jz\n"
  76. "0gSb7AeR9/AaJgg1FVUantmX7Ja60qLQW4O6DzTJgTGtuKEhaX3wNjpH5aKw8Ifn\n"
  77. "gVdZrm9hBKGQCxC5JjVjcrKRXKjj7iKf+d0UN57q9BlKcqw+r+ET2Lqf2jnm1XTt\n"
  78. "O1i6VkEGCZxSKdy2jb0d1kHNJonXyrW7mukfclO2LKqDwWYr2efu4wv0Dt9ttWeA\n"
  79. "jL6taU7O3aGwjTibLW8qcneWKQogIwnmvY2TsDTtL7Pr+zXpIeBOvuu9+IEGV5nm\n"
  80. "j4pVrlApKDF7+hhhYyevJSEfnImCwgeji3pZ5CnFEYASBMEGZmGmWtJyZ/sDkrTe\n"
  81. "RjyOV22NaHWtu7HISaOgU/inG8NwGsOL91osnmE+hB07vr44Blaz2oHQhtEZb35k\n"
  82. "YLeP+sf4MK0iQy/aKnLcZBHig8/m4MIPNKgpHu/MJ03pbiNiUzV34q4IkuvQiEFf\n"
  83. "9N/p4HHRx6789Ndf1b8+iW0VtftfTt/HXYnSw2I1InFfB8KmnC20gYIQEorGPUuX\n"
  84. "32yYXSjYNdyWZI52PwX57LD/A5YwkuTowib5MyYFoA2Po51B9bHNCTwzN1RTfGbH\n"
  85. "-----END RSA PRIVATE KEY-----\n";
  86. /*Public key generated using
  87. openssl rsa -in priv.pem -passin pass:ThisIsMyPassphrase -pubout -out pub.pem
  88. */
  89. const char * pubKeyPassphrase =
  90. "-----BEGIN PUBLIC KEY-----\n"
  91. "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCWnKkGM0l3Y6pKhxMq87hAGBL6\n"
  92. "FfEo2HC6XCSQuaAMLkdf7Yjn3FpvFIEO6A1ZYJy70cT8+HOFta+sSUyMn2fDc5cv\n"
  93. "VdX8v7XCycYXEBeZ4KsTCHHPCUoO/nxNbxhNz09T8dx/JsIH50LHipR6FTLTSCXR\n"
  94. "N9KVLaPXs5DdQx6PjQIDAQAB\n"
  95. "-----END PUBLIC KEY-----\n";
  96. /* ============================================================= */
  97. using namespace cryptohelper;
  98. #ifdef _USE_OPENSSL
  99. class CryptoUnitTest : public CppUnit::TestFixture
  100. {
  101. public:
  102. CPPUNIT_TEST_SUITE(CryptoUnitTest);
  103. CPPUNIT_TEST(digiSignTests);
  104. CPPUNIT_TEST(pkeEncryptDecryptTest);
  105. CPPUNIT_TEST(pkeEncryptDecryptPassphraseTest);
  106. CPPUNIT_TEST(pkeParallelTest);
  107. CPPUNIT_TEST(aesEncryptDecryptTests);
  108. CPPUNIT_TEST(aesWithRsaEncryptedKey);
  109. CPPUNIT_TEST(aesParallelTest);
  110. CPPUNIT_TEST_SUITE_END();
  111. protected:
  112. void asyncDigiSignUnitTest(IDigitalSignatureManager * _dsm)
  113. {
  114. class casyncfor: public CAsyncFor
  115. {
  116. IDigitalSignatureManager * dsm;
  117. public:
  118. casyncfor(IDigitalSignatureManager * _dsm)
  119. {
  120. dsm = _dsm;
  121. }
  122. void Do(unsigned idx)
  123. {
  124. VStringBuffer text("I am here %d", idx);
  125. StringBuffer sig;
  126. bool ok = dsm->digiSign(sig, text);
  127. if (!ok)
  128. printf("Asynchronous asyncDigiSignUnitTest() test %d failed!\n", idx);
  129. ASSERT(ok);
  130. }
  131. } afor(_dsm);
  132. printf("Executing 1000 asyncDigiSignUnitTest() operations\n");
  133. afor.For(1000,20,true,true);
  134. printf("Asynchronous asyncDigiSignUnitTest() test complete\n");
  135. }
  136. void asyncDigiVerifyUnitTest(IDigitalSignatureManager * _dsm)
  137. {
  138. class casyncfor: public CAsyncFor
  139. {
  140. IDigitalSignatureManager * dsm;
  141. StringBuffer text;
  142. StringBuffer sig;
  143. public:
  144. casyncfor(IDigitalSignatureManager * _dsm)
  145. {
  146. dsm = _dsm;
  147. text.set("I am here");
  148. bool ok = dsm->digiSign(text, sig);
  149. if (!ok)
  150. printf("Asynchronous asyncDigiVerifyUnitTest() failed in digiSign!\n");
  151. ASSERT(ok);
  152. }
  153. void Do(unsigned idx)
  154. {
  155. bool ok = dsm->digiVerify(sig, text);
  156. if (!ok)
  157. printf("Asynchronous asyncDigiVerifyUnitTest() test %d failed!\n", idx);
  158. ASSERT(ok);
  159. }
  160. } afor(_dsm);
  161. printf("Executing 1000 asyncDigiVerifyUnitTest() operations\n");
  162. afor.For(1000,20,true,true);
  163. printf("Asynchronous asyncDigiVerifyUnitTest() test complete\n");
  164. }
  165. void asyncDigiSignAndVerifyUnitTest(IDigitalSignatureManager * _dsm)
  166. {
  167. class casyncfor: public CAsyncFor
  168. {
  169. IDigitalSignatureManager * dsm;
  170. public:
  171. casyncfor(IDigitalSignatureManager * _dsm)
  172. {
  173. dsm = _dsm;
  174. }
  175. void Do(unsigned idx)
  176. {
  177. VStringBuffer text("I am here %d", idx);
  178. StringBuffer sig;
  179. bool ok = dsm->digiSign(text, sig);
  180. if (!ok)
  181. printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test %d failed!\n", idx);
  182. ASSERT(ok);
  183. ok = dsm->digiVerify(sig, text);
  184. if (!ok)
  185. printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test %d failed!\n", idx);
  186. ASSERT(ok);
  187. }
  188. } afor(_dsm);
  189. printf("Executing 1000 asynchronous asyncDigiSignAndVerifyUnitTest() operations\n");
  190. afor.For(1000,20,true,true);
  191. printf("Asynchronous asyncDigiSignAndVerifyUnitTest() test complete\n");
  192. }
  193. void digiSignTests()
  194. {
  195. Owned<IException> exception;
  196. CppUnit::Exception *cppunitException;
  197. const char * text1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  198. const char * text2 = "~`!@#$%^&*()_-+=0123456789{[}]:;\"'<,>.?/'";
  199. const char * text3 = "W20180301-154415;ECLUsername";
  200. StringBuffer sig1;
  201. StringBuffer sig2;
  202. StringBuffer sig3;
  203. try
  204. {
  205. printf("\nExecuting digiSign() unit tests\n");
  206. //Create instance of digital signature manager
  207. Owned<IDigitalSignatureManager> dsm(createDigitalSignatureManagerInstanceFromKeys(pubKey, privKey, nullptr));
  208. printf("digiSign() test 1\n");
  209. StringBuffer txt(text1);
  210. bool ok = dsm->digiSign(sig1.clear(), text1);
  211. ASSERT(ok);
  212. ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
  213. ASSERT(!sig1.isEmpty());//signature should be populated
  214. StringBuffer sig(sig1);
  215. ok = dsm->digiVerify(sig1, text1);
  216. ASSERT(ok);
  217. ASSERT(0 == strcmp(text1, txt.str()));//source string should be unchanged
  218. ASSERT(0 == strcmp(sig.str(), sig1.str()));//signature should be unchanged
  219. printf("digiSign() test 2\n");
  220. ok = dsm->digiVerify(sig1, text1);
  221. ASSERT(ok);
  222. ok = dsm->digiVerify(sig1, text1);
  223. ASSERT(ok);
  224. printf("digiSign() test 3\n");
  225. ok = dsm->digiSign(sig2.clear(), text2);
  226. ASSERT(ok);
  227. ok = dsm->digiVerify(sig2, text2);
  228. ASSERT(ok);
  229. ok = dsm->digiSign(sig2.clear(), text2);
  230. ASSERT(ok);
  231. ok = dsm->digiVerify(sig2, text2);
  232. ASSERT(ok);
  233. printf("digiSign() test 4\n");
  234. ok = dsm->digiVerify(sig1, text1);
  235. ASSERT(ok);
  236. printf("digiSign() test 5\n");
  237. ok = dsm->digiVerify(sig2, text2);
  238. ASSERT(ok);
  239. printf("digiSign() test 6\n");
  240. ok = dsm->digiVerify(sig2, text1);
  241. ASSERT(!ok);//should fail
  242. printf("digiSign() test 7\n");
  243. ok = dsm->digiVerify(sig1, text2);
  244. ASSERT(!ok);//should fail
  245. printf("digiSign() test 8\n");
  246. ok = dsm->digiSign(sig3.clear(), text3);
  247. ASSERT(ok);
  248. printf("digiSign() test 9\n");
  249. ok = dsm->digiVerify(sig1, text3);
  250. ASSERT(!ok);//should fail
  251. ok = dsm->digiVerify(sig2, text3);
  252. ASSERT(!ok);//should fail
  253. ok = dsm->digiVerify(sig3, text3);
  254. ASSERT(ok);
  255. //Perform
  256. printf("digiSign() loop test\n");
  257. unsigned now = msTick();
  258. for (int x=0; x<1000; x++)
  259. {
  260. dsm->digiSign(sig3.clear(), text3);
  261. }
  262. printf("digiSign() 1000 iterations took %d MS\n", msTick() - now);
  263. printf("digiVerify() loop test\n");
  264. now = msTick();
  265. for (int x=0; x<1000; x++)
  266. {
  267. dsm->digiVerify(sig3, text3);
  268. }
  269. printf("digiverify 1000 iterations took %d MS\n", msTick() - now);
  270. now = msTick();
  271. printf("\nAsynchronous test digiSign\n");
  272. asyncDigiSignUnitTest(dsm);
  273. printf("digiSign 1000 async iterations took %d MS\n", msTick() - now);
  274. now = msTick();
  275. printf("\nAsynchronous test digiVerify\n");
  276. asyncDigiVerifyUnitTest(dsm);
  277. printf("digiverify 1000 async iterations took %d MS\n", msTick() - now);
  278. now = msTick();
  279. printf("\nAsynchronous test digiSign and digiVerify\n");
  280. asyncDigiSignAndVerifyUnitTest(dsm);
  281. printf("digiSign/digiverify 1000 async iterations took %d MS\n", msTick() - now);
  282. }
  283. catch (IException *e)
  284. {
  285. StringBuffer err;
  286. e->errorMessage(err);
  287. printf("Digisign IException thrown:%s\n", err.str());
  288. exception.setown(e);
  289. }
  290. catch (CppUnit::Exception &e)
  291. {
  292. printf("Digisign CppUnit::Exception thrown\n");
  293. cppunitException = e.clone();
  294. }
  295. printf("Completed executing digiSign() unit tests\n");
  296. }
  297. void _pkeEncryptDecryptTest()
  298. {
  299. try
  300. {
  301. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey);
  302. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  303. // create random data
  304. MemoryBuffer toEncryptMb;
  305. fillRandomData(245, toEncryptMb); // max for RSA
  306. MemoryBuffer pkeMb;
  307. publicKeyEncrypt(pkeMb, toEncryptMb.length(), toEncryptMb.bytes(), *publicKey);
  308. MemoryBuffer decryptedMb;
  309. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  310. ASSERT(toEncryptMb.length() == decryptedMb.length());
  311. ASSERT(0 == memcmp(toEncryptMb.bytes(), decryptedMb.bytes(), toEncryptMb.length()));
  312. }
  313. catch (IException *e)
  314. {
  315. StringBuffer err;
  316. e->errorMessage(err);
  317. printf("pkeEncryptDecryptTest IException thrown:%s\n", err.str());
  318. throw;
  319. }
  320. catch (CppUnit::Exception &e)
  321. {
  322. printf("pkeEncryptDecryptTest CppUnit::Exception thrown\n");
  323. throw;
  324. }
  325. }
  326. void pkeEncryptDecryptTest()
  327. {
  328. printf("\nExecuting pkeEncryptDecryptTest() unit tests\n");
  329. _pkeEncryptDecryptTest();
  330. }
  331. void _pkeEncryptDecryptPassphraseTest()
  332. {
  333. try
  334. {
  335. // create random data
  336. MemoryBuffer toEncryptMb;
  337. fillRandomData(64, toEncryptMb);
  338. MemoryBuffer pkeMb;
  339. MemoryBuffer decryptedMb;
  340. /////////////////////////////////////
  341. //PKE tests using a passphrase string
  342. /////////////////////////////////////
  343. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKeyPassphrase);
  344. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKeyPassphrase, "ThisIsMyPassphrase");
  345. publicKeyEncrypt(pkeMb, toEncryptMb.length(), toEncryptMb.bytes(), *publicKey);
  346. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  347. ASSERT(toEncryptMb.length() == decryptedMb.length());
  348. ASSERT(0 == memcmp(toEncryptMb.bytes(), decryptedMb.bytes(), toEncryptMb.length()));
  349. /////////////////////////////////////
  350. //PKE tests using a passphrase buffer
  351. /////////////////////////////////////
  352. Owned<CLoadedKey> publicKeyPassphrase = loadPublicKeyFromMemory(pubKeyPassphrase);
  353. Owned<CLoadedKey> privateKeyPassphrase = loadPrivateKeyFromMemory(privKeyPassphrase, 18, "ThisIsMyPassphrase");
  354. pkeMb.clear();
  355. publicKeyEncrypt(pkeMb, toEncryptMb.length(), toEncryptMb.bytes(), *publicKeyPassphrase);
  356. decryptedMb.clear();
  357. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKeyPassphrase);
  358. ASSERT(toEncryptMb.length() == decryptedMb.length());
  359. ASSERT(0 == memcmp(toEncryptMb.bytes(), decryptedMb.bytes(), toEncryptMb.length()));
  360. }
  361. catch (IException *e)
  362. {
  363. StringBuffer err;
  364. e->errorMessage(err);
  365. printf("pkeEncryptDecryptPassphraseTest IException thrown:%s\n", err.str());
  366. throw;
  367. }
  368. catch (CppUnit::Exception &e)
  369. {
  370. printf("pkeEncryptDecryptPassphraseTest CppUnit::Exception thrown\n");
  371. throw;
  372. }
  373. }
  374. void pkeEncryptDecryptPassphraseTest()
  375. {
  376. printf("\nExecuting pkeEncryptDecryptPassphraseTest() unit tests\n");
  377. _pkeEncryptDecryptPassphraseTest();
  378. }
  379. void pkeParallelTest()
  380. {
  381. class CAsyncfor : public CAsyncFor
  382. {
  383. std::function<void()> testFunc;
  384. public:
  385. CAsyncfor(std::function<void()> _testFunc) : testFunc(_testFunc)
  386. {
  387. }
  388. void Do(unsigned idx)
  389. {
  390. testFunc();
  391. }
  392. } afor(std::bind(&CryptoUnitTest::_pkeEncryptDecryptTest, this));
  393. printf("\nExecuting 1000 asynchronous pkeParallelTest() operations\n");
  394. CCycleTimer timer;
  395. afor.For(1000, 20, true, true);
  396. printf("Asynchronous pkeParallelTest() test completed in %u ms\n", timer.elapsedMs());
  397. }
  398. void aesEncryptDecryptTests()
  399. {
  400. try
  401. {
  402. printf("\nExecuting aesEncryptDecryptTests() unit tests\n");
  403. // create random data
  404. MemoryBuffer messageMb, encryptedMessageMb, decryptedMessageMb;
  405. char aesKey[aesMaxKeySize];
  406. char aesIV[aesBlockSize];
  407. fillRandomData(aesMaxKeySize, aesKey);
  408. fillRandomData(aesBlockSize, aesIV);
  409. fillRandomData(1024*100, messageMb);
  410. printf("aesEncryptDecryptTests with %u bytes with 256bit aes key\n", messageMb.length());
  411. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  412. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  413. ASSERT(messageMb.length() == decryptedMessageMb.length());
  414. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  415. printf("aesEncryptDecryptTests with %u bytes with 192bit aes key\n", messageMb.length());
  416. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), 192/8, aesKey, aesIV);
  417. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), 192/8, aesKey, aesIV);
  418. ASSERT(messageMb.length() == decryptedMessageMb.length());
  419. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  420. printf("aesEncryptDecryptTests with %u bytes with 128bit aes key\n", messageMb.length());
  421. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), 128/8, aesKey, aesIV);
  422. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), 128/8, aesKey, aesIV);
  423. ASSERT(messageMb.length() == decryptedMessageMb.length());
  424. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  425. messageMb.clear(); // 0 length test
  426. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  427. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  428. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  429. ASSERT(messageMb.length() == decryptedMessageMb.length());
  430. fillRandomData(1, messageMb.clear()); // 1 byte test
  431. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  432. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  433. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  434. ASSERT(messageMb.length() == decryptedMessageMb.length());
  435. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  436. fillRandomData(cryptohelper::aesBlockSize-1, messageMb.clear()); // aesBlockSize-1 test
  437. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  438. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  439. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  440. ASSERT(messageMb.length() == decryptedMessageMb.length());
  441. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  442. fillRandomData(cryptohelper::aesBlockSize, messageMb.clear()); // aesBlockSize test
  443. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  444. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  445. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  446. ASSERT(messageMb.length() == decryptedMessageMb.length());
  447. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  448. fillRandomData(cryptohelper::aesBlockSize+1, messageMb.clear()); // aesBlockSize+1 test
  449. printf("aesEncryptDecryptTests with %u bytes\n", messageMb.length());
  450. aesEncrypt(encryptedMessageMb.clear(), messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  451. aesDecrypt(decryptedMessageMb.clear(), encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  452. ASSERT(messageMb.length() == decryptedMessageMb.length());
  453. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  454. }
  455. catch (IException *e)
  456. {
  457. StringBuffer err;
  458. e->errorMessage(err);
  459. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  460. throw;
  461. }
  462. catch (CppUnit::Exception &e)
  463. {
  464. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  465. throw;
  466. }
  467. }
  468. void aesWithRsaEncryptedKey()
  469. {
  470. try
  471. {
  472. printf("\nExecuting aesWithRsaEncryptedKey() unit tests\n");
  473. // create random data
  474. MemoryBuffer messageMb;
  475. fillRandomData(1024*100, messageMb);
  476. char aesKey[aesMaxKeySize];
  477. char aesIV[aesBlockSize];
  478. fillRandomData(aesMaxKeySize, aesKey);
  479. fillRandomData(aesBlockSize, aesIV);
  480. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey);
  481. MemoryBuffer encryptedMessageMb;
  482. aesEncryptWithRSAEncryptedKey(encryptedMessageMb, messageMb.length(), messageMb.bytes(), *publicKey);
  483. // would normally be server side
  484. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  485. MemoryBuffer decryptedMessageMb;
  486. aesDecryptWithRSAEncryptedKey(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), *privateKey);
  487. ASSERT(messageMb.length() == decryptedMessageMb.length());
  488. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  489. }
  490. catch (IException *e)
  491. {
  492. StringBuffer err;
  493. e->errorMessage(err);
  494. printf("aesWithRsaEncryptedKey IException thrown:%s\n", err.str());
  495. throw;
  496. }
  497. catch (CppUnit::Exception &e)
  498. {
  499. printf("aesWithRsaEncryptedKey CppUnit::Exception thrown\n");
  500. throw;
  501. }
  502. }
  503. void aesParallelTest()
  504. {
  505. class CAsyncfor : public CAsyncFor
  506. {
  507. MemoryBuffer messageMb;
  508. char aesKey[aesMaxKeySize];
  509. char aesIV[aesBlockSize];
  510. public:
  511. CAsyncfor()
  512. {
  513. // create random key
  514. fillRandomData(aesMaxKeySize, aesKey);
  515. fillRandomData(aesBlockSize, aesIV);
  516. // create random data
  517. fillRandomData(1024*100, messageMb);
  518. }
  519. void Do(unsigned idx)
  520. {
  521. MemoryBuffer encryptedMessageMb;
  522. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  523. MemoryBuffer decryptedMessageMb;
  524. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  525. ASSERT(messageMb.length() == decryptedMessageMb.length());
  526. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  527. }
  528. } afor;
  529. printf("\nExecuting 1000 asynchronous aesParallelTest() operations\n");
  530. CCycleTimer timer;
  531. afor.For(1000, 20, true, true);
  532. printf("Asynchronous aesParallelTest() test completed in %u ms\n", timer.elapsedMs());
  533. }
  534. };
  535. class CryptoTestTiming : public CppUnit::TestFixture
  536. {
  537. size32_t dataSz = 0x100000 * 10; // 10MB
  538. public:
  539. CPPUNIT_TEST_SUITE(CryptoTestTiming);
  540. CPPUNIT_TEST(aesSpeedTest);
  541. CPPUNIT_TEST(rsaSpeedTest);
  542. CPPUNIT_TEST(rsaKeyLoadSpeedTest);
  543. CPPUNIT_TEST(aesCompareJlibVsCryptoHelper);
  544. CPPUNIT_TEST_SUITE_END();
  545. void aesCompareJlibVsCryptoHelper()
  546. {
  547. MemoryBuffer messageMb, encryptedMessageMb, decryptedMessageMb;
  548. char aesKey[aesMaxKeySize];
  549. char aesIV[aesBlockSize];
  550. // create random key
  551. fillRandomData(aesMaxKeySize, aesKey);
  552. fillRandomData(aesBlockSize, aesIV);
  553. // create random data
  554. fillRandomData(dataSz, messageMb);
  555. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  556. CCycleTimer timer;
  557. cryptohelper::aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  558. printf("OPENSSL AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  559. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  560. timer.reset();
  561. cryptohelper::aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  562. printf("OPENSSL AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  563. ASSERT(messageMb.length() == decryptedMessageMb.length());
  564. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  565. encryptedMessageMb.clear();
  566. timer.reset();
  567. jlib::aesEncrypt(aesKey, aesMaxKeySize, messageMb.bytes(), messageMb.length(), encryptedMessageMb);
  568. printf("JLIB AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  569. decryptedMessageMb.clear();
  570. timer.reset();
  571. jlib::aesDecrypt(aesKey, aesMaxKeySize, encryptedMessageMb.bytes(), encryptedMessageMb.length(), decryptedMessageMb);
  572. printf("JLIB AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  573. ASSERT(messageMb.length() == decryptedMessageMb.length());
  574. ASSERT(0 == memcmp(messageMb.bytes(), decryptedMessageMb.bytes(), messageMb.length()));
  575. }
  576. void aesSpeedTest()
  577. {
  578. MemoryBuffer messageMb;
  579. char aesKey[aesMaxKeySize];
  580. char aesIV[aesBlockSize];
  581. // create random key
  582. fillRandomData(aesMaxKeySize, aesKey);
  583. fillRandomData(aesBlockSize, aesIV);
  584. // create random data
  585. fillRandomData(dataSz, messageMb);
  586. MemoryBuffer encryptedMessageMb;
  587. encryptedMessageMb.ensureCapacity(dataSz+aesBlockSize);
  588. CCycleTimer timer;
  589. aesEncrypt(encryptedMessageMb, messageMb.length(), messageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  590. printf("AES %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  591. MemoryBuffer decryptedMessageMb;
  592. decryptedMessageMb.ensureCapacity(encryptedMessageMb.length()+aesBlockSize);
  593. timer.reset();
  594. aesDecrypt(decryptedMessageMb, encryptedMessageMb.length(), encryptedMessageMb.bytes(), aesMaxKeySize, aesKey, aesIV);
  595. printf("AES %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  596. }
  597. void rsaSpeedTest()
  598. {
  599. // create random data
  600. MemoryBuffer messageMb;
  601. fillRandomData(dataSz, messageMb);
  602. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey);
  603. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  604. MemoryBuffer encryptedMessageMb;
  605. MemoryBuffer decryptedMessageMb;
  606. // pre-alloc memory, so as not part of the timing
  607. size32_t maxPerEncryptSz = 245;
  608. unsigned numPackets = ((dataSz + (maxPerEncryptSz-1)) / maxPerEncryptSz);
  609. size32_t dstMaxSz = numPackets * 256; // approx
  610. encryptedMessageMb.ensureCapacity(dstMaxSz);
  611. const byte *src = messageMb.bytes();
  612. byte *dst = (byte *)encryptedMessageMb.bufferBase();
  613. size32_t remaining = dataSz;
  614. size32_t encryptPacketSz = 256;
  615. CCycleTimer timer;
  616. while (true)
  617. {
  618. size32_t cp = remaining>maxPerEncryptSz ? maxPerEncryptSz : remaining;
  619. size_t eSz = publicKeyEncrypt(dst, dstMaxSz, cp, src, *publicKey);
  620. assertex(eSz);
  621. assertex(eSz == encryptPacketSz); //consistent for size being encrypted, assumed on decrypt
  622. src += cp;
  623. remaining -= cp;
  624. dst += eSz;
  625. dstMaxSz -= eSz;
  626. if (0 == remaining)
  627. break;
  628. }
  629. encryptedMessageMb.rewrite(dst-(byte*)encryptedMessageMb.bufferBase());
  630. printf("RSA %u MB encrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  631. size32_t encryptedDataSz = encryptedMessageMb.length();
  632. remaining = encryptedDataSz;
  633. src = encryptedMessageMb.bytes();
  634. dstMaxSz = ((numPackets-1) * maxPerEncryptSz) + encryptPacketSz; // because encrypt always needs buffer to have enough room for encryptPacketSz
  635. decryptedMessageMb.ensureCapacity(dstMaxSz);
  636. dst = (byte *)decryptedMessageMb.bufferBase();
  637. timer.reset();
  638. while (true)
  639. {
  640. size_t eSz = privateKeyDecrypt(dst, dstMaxSz, encryptPacketSz, src, *privateKey);
  641. assertex(eSz);
  642. assertex(eSz <= maxPerEncryptSz);
  643. src += encryptPacketSz;
  644. remaining -= encryptPacketSz;
  645. dst += eSz;
  646. dstMaxSz -= eSz;
  647. if (0 == remaining)
  648. break;
  649. }
  650. printf("RSA %u MB decrypt time: %u ms\n", dataSz/0x100000, timer.elapsedMs());
  651. }
  652. void rsaKeyLoadSpeedTest()
  653. {
  654. // create random data
  655. size32_t dataSz = 245;
  656. MemoryBuffer messageMb;
  657. fillRandomData(dataSz, messageMb);
  658. unsigned numCycles = 1000;
  659. CCycleTimer timer;
  660. for (unsigned i=0; i<numCycles; i++)
  661. {
  662. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey);
  663. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  664. MemoryBuffer pkeMb;
  665. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  666. MemoryBuffer decryptedMb;
  667. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  668. }
  669. printf("RSA %u cycles - reloading keys each iteration - %u ms\n", numCycles, timer.elapsedMs());
  670. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(pubKey);
  671. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privKey, nullptr);
  672. timer.reset();
  673. for (unsigned i=0; i<numCycles; i++)
  674. {
  675. MemoryBuffer pkeMb;
  676. publicKeyEncrypt(pkeMb, messageMb.length(), messageMb.bytes(), *publicKey);
  677. MemoryBuffer decryptedMb;
  678. privateKeyDecrypt(decryptedMb, pkeMb.length(), pkeMb.bytes(), *privateKey);
  679. }
  680. printf("RSA %u cycles - reusing loaded keys - %u ms\n", numCycles, timer.elapsedMs());
  681. }
  682. };
  683. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoUnitTest );
  684. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoUnitTest, "CryptoUnitTest" );
  685. CPPUNIT_TEST_SUITE_REGISTRATION( CryptoTestTiming );
  686. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( CryptoTestTiming, "CryptoTestTiming" );
  687. #endif
  688. #endif // _USE_CPPUNIT