test-crypto.cpp 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <LibC/limits.h>
  27. #include <LibCore/ArgsParser.h>
  28. #include <LibCore/EventLoop.h>
  29. #include <LibCore/File.h>
  30. #include <LibCrypto/Authentication/HMAC.h>
  31. #include <LibCrypto/BigInt/UnsignedBigInteger.h>
  32. #include <LibCrypto/Cipher/AES.h>
  33. #include <LibCrypto/Hash/MD5.h>
  34. #include <LibCrypto/Hash/SHA1.h>
  35. #include <LibCrypto/Hash/SHA2.h>
  36. #include <LibCrypto/PK/RSA.h>
  37. #include <LibLine/Editor.h>
  38. #include <LibTLS/TLSv12.h>
  39. #include <stdio.h>
  40. #include <time.h>
  41. static const char* secret_key = "WellHelloFreinds";
  42. static const char* suite = nullptr;
  43. static const char* filename = nullptr;
  44. static const char* server = nullptr;
  45. static int key_bits = 128;
  46. static bool binary = false;
  47. static bool interactive = false;
  48. static bool run_tests = false;
  49. static int port = 443;
  50. static struct timeval start_time {
  51. 0, 0
  52. };
  53. static struct timezone tz;
  54. static bool encrypting = true;
  55. constexpr const char* DEFAULT_DIGEST_SUITE { "HMAC-SHA256" };
  56. constexpr const char* DEFAULT_HASH_SUITE { "SHA256" };
  57. constexpr const char* DEFAULT_CIPHER_SUITE { "AES_CBC" };
  58. constexpr const char* DEFAULT_SERVER { "www.google.com" };
  59. constexpr int DEFAULT_PORT { 443 };
  60. // listAllTests
  61. // Cipher
  62. int aes_cbc_tests();
  63. // Hash
  64. int md5_tests();
  65. int sha1_tests();
  66. int sha256_tests();
  67. int sha512_tests();
  68. // Authentication
  69. int hmac_md5_tests();
  70. int hmac_sha256_tests();
  71. int hmac_sha512_tests();
  72. // Public-Key
  73. int rsa_tests();
  74. // TLS
  75. int tls_tests();
  76. // Big Integer
  77. int bigint_tests();
  78. // stop listing tests
  79. void print_buffer(const ByteBuffer& buffer, int split)
  80. {
  81. for (size_t i = 0; i < buffer.size(); ++i) {
  82. if (split > 0) {
  83. if (i % split == 0 && i) {
  84. printf(" ");
  85. for (size_t j = i - split; j < i; ++j) {
  86. auto ch = buffer[j];
  87. printf("%c", ch >= 32 && ch <= 127 ? ch : '.'); // silly hack
  88. }
  89. puts("");
  90. }
  91. }
  92. printf("%02x ", buffer[i]);
  93. }
  94. puts("");
  95. }
  96. Core::EventLoop loop;
  97. int run(Function<void(const char*, size_t)> fn)
  98. {
  99. if (interactive) {
  100. Line::Editor editor;
  101. editor.initialize();
  102. for (;;) {
  103. auto line_result = editor.get_line("> ");
  104. if (line_result.is_error())
  105. break;
  106. auto& line = line_result.value();
  107. if (line == ".wait") {
  108. loop.exec();
  109. } else {
  110. fn(line.characters(), line.length());
  111. loop.pump();
  112. }
  113. }
  114. } else {
  115. if (filename == nullptr) {
  116. puts("must specify a file name");
  117. return 1;
  118. }
  119. if (!Core::File::exists(filename)) {
  120. puts("File does not exist");
  121. return 1;
  122. }
  123. auto file = Core::File::open(filename, Core::IODevice::OpenMode::ReadOnly);
  124. if (file.is_error()) {
  125. printf("That's a weird file man...\n");
  126. return 1;
  127. }
  128. auto buffer = file.value()->read_all();
  129. fn((const char*)buffer.data(), buffer.size());
  130. loop.exec();
  131. }
  132. return 0;
  133. }
  134. void tls(const char* message, size_t len)
  135. {
  136. static RefPtr<TLS::TLSv12> tls;
  137. static ByteBuffer write {};
  138. if (!tls) {
  139. tls = TLS::TLSv12::construct(nullptr);
  140. tls->connect(server ?: DEFAULT_SERVER, port);
  141. tls->on_tls_ready_to_read = [](auto& tls) {
  142. auto buffer = tls.read();
  143. if (buffer.has_value())
  144. fprintf(stdout, "%.*s", (int)buffer.value().size(), buffer.value().data());
  145. };
  146. tls->on_tls_ready_to_write = [&](auto&) {
  147. if (write.size()) {
  148. tls->write(write);
  149. write.clear();
  150. }
  151. };
  152. tls->on_tls_error = [&](auto) {
  153. loop.quit(1);
  154. };
  155. tls->on_tls_finished = [&]() {
  156. loop.quit(0);
  157. };
  158. }
  159. write.append(message, len);
  160. write.append("\r\n", 2);
  161. }
  162. void aes_cbc(const char* message, size_t len)
  163. {
  164. auto buffer = ByteBuffer::wrap(message, len);
  165. // FIXME: Take iv as an optional parameter
  166. auto iv = ByteBuffer::create_zeroed(Crypto::Cipher::AESCipher::block_size());
  167. if (encrypting) {
  168. Crypto::Cipher::AESCipher::CBCMode cipher(ByteBuffer::wrap(secret_key, strlen(secret_key)), key_bits, Crypto::Cipher::Intent::Encryption);
  169. auto enc = cipher.create_aligned_buffer(buffer.size());
  170. cipher.encrypt(buffer, enc, iv);
  171. if (binary)
  172. printf("%.*s", (int)enc.size(), enc.data());
  173. else
  174. print_buffer(enc, Crypto::Cipher::AESCipher::block_size());
  175. } else {
  176. Crypto::Cipher::AESCipher::CBCMode cipher(ByteBuffer::wrap(secret_key, strlen(secret_key)), key_bits, Crypto::Cipher::Intent::Decryption);
  177. auto dec = cipher.create_aligned_buffer(buffer.size());
  178. cipher.decrypt(buffer, dec, iv);
  179. printf("%.*s\n", (int)dec.size(), dec.data());
  180. }
  181. }
  182. void md5(const char* message, size_t len)
  183. {
  184. auto digest = Crypto::Hash::MD5::hash((const u8*)message, len);
  185. if (binary)
  186. printf("%.*s", (int)Crypto::Hash::MD5::digest_size(), digest.data);
  187. else
  188. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::MD5::digest_size()), -1);
  189. }
  190. void hmac_md5(const char* message, size_t len)
  191. {
  192. Crypto::Authentication::HMAC<Crypto::Hash::MD5> hmac(secret_key);
  193. auto mac = hmac.process((const u8*)message, len);
  194. if (binary)
  195. printf("%.*s", (int)hmac.digest_size(), mac.data);
  196. else
  197. print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
  198. }
  199. void sha1(const char* message, size_t len)
  200. {
  201. auto digest = Crypto::Hash::SHA1::hash((const u8*)message, len);
  202. if (binary)
  203. printf("%.*s", (int)Crypto::Hash::SHA1::digest_size(), digest.data);
  204. else
  205. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA1::digest_size()), -1);
  206. }
  207. void sha256(const char* message, size_t len)
  208. {
  209. auto digest = Crypto::Hash::SHA256::hash((const u8*)message, len);
  210. if (binary)
  211. printf("%.*s", (int)Crypto::Hash::SHA256::digest_size(), digest.data);
  212. else
  213. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA256::digest_size()), -1);
  214. }
  215. void hmac_sha256(const char* message, size_t len)
  216. {
  217. Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac(secret_key);
  218. auto mac = hmac.process((const u8*)message, len);
  219. if (binary)
  220. printf("%.*s", (int)hmac.digest_size(), mac.data);
  221. else
  222. print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
  223. }
  224. void sha512(const char* message, size_t len)
  225. {
  226. auto digest = Crypto::Hash::SHA512::hash((const u8*)message, len);
  227. if (binary)
  228. printf("%.*s", (int)Crypto::Hash::SHA512::digest_size(), digest.data);
  229. else
  230. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA512::digest_size()), -1);
  231. }
  232. void hmac_sha512(const char* message, size_t len)
  233. {
  234. Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac(secret_key);
  235. auto mac = hmac.process((const u8*)message, len);
  236. if (binary)
  237. printf("%.*s", (int)hmac.digest_size(), mac.data);
  238. else
  239. print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
  240. }
  241. auto main(int argc, char** argv) -> int
  242. {
  243. const char* mode = nullptr;
  244. Core::ArgsParser parser;
  245. parser.add_positional_argument(mode, "mode to operate in ('list' to see modes and descriptions)", "mode");
  246. parser.add_option(secret_key, "Set the secret key (default key is 'WellHelloFriends')", "secret-key", 'k', "secret key");
  247. parser.add_option(key_bits, "Size of the key", "key-bits", 'b', "key-bits");
  248. parser.add_option(filename, "Read from file", "file", 'f', "from file");
  249. parser.add_option(binary, "Force binary output", "force-binary", 0);
  250. parser.add_option(interactive, "REPL mode", "interactive", 'i');
  251. parser.add_option(run_tests, "Run tests for the specified suite", "tests", 't');
  252. parser.add_option(suite, "Set the suite used", "suite-name", 'n', "suite name");
  253. parser.add_option(server, "Set the server to talk to (only for `tls')", "server-address", 's', "server-address");
  254. parser.add_option(port, "Set the port to talk to (only for `tls')", "port", 'p', "port");
  255. parser.parse(argc, argv);
  256. StringView mode_sv { mode };
  257. if (mode_sv == "list") {
  258. puts("test-crypto modes");
  259. puts("\tdigest - Access digest (authentication) functions");
  260. puts("\thash - Access hash functions");
  261. puts("\tencrypt -- Access encryption functions");
  262. puts("\tdecrypt -- Access decryption functions");
  263. puts("\ttls -- Connect to a peer over TLS 1.2");
  264. puts("\tlist -- List all known modes");
  265. puts("these modes only contain tests");
  266. puts("\ttest -- Run every test suite");
  267. puts("\tbigint -- Run big integer test suite");
  268. puts("\tpk -- Run Public-key system tests");
  269. return 0;
  270. }
  271. if (mode_sv == "hash") {
  272. if (suite == nullptr)
  273. suite = DEFAULT_HASH_SUITE;
  274. StringView suite_sv { suite };
  275. if (suite_sv == "MD5") {
  276. if (run_tests)
  277. return md5_tests();
  278. return run(md5);
  279. }
  280. if (suite_sv == "SHA1") {
  281. if (run_tests)
  282. return sha1_tests();
  283. return run(sha1);
  284. }
  285. if (suite_sv == "SHA256") {
  286. if (run_tests)
  287. return sha256_tests();
  288. return run(sha256);
  289. }
  290. if (suite_sv == "SHA512") {
  291. if (run_tests)
  292. return sha512_tests();
  293. return run(sha512);
  294. }
  295. printf("unknown hash function '%s'\n", suite);
  296. return 1;
  297. }
  298. if (mode_sv == "digest") {
  299. if (suite == nullptr)
  300. suite = DEFAULT_DIGEST_SUITE;
  301. StringView suite_sv { suite };
  302. if (suite_sv == "HMAC-MD5") {
  303. if (run_tests)
  304. return hmac_md5_tests();
  305. return run(hmac_md5);
  306. }
  307. if (suite_sv == "HMAC-SHA256") {
  308. if (run_tests)
  309. return hmac_sha256_tests();
  310. return run(hmac_sha256);
  311. }
  312. if (suite_sv == "HMAC-SHA512") {
  313. if (run_tests)
  314. return hmac_sha512_tests();
  315. return run(hmac_sha512);
  316. }
  317. printf("unknown hash function '%s'\n", suite);
  318. return 1;
  319. }
  320. if (mode_sv == "pk") {
  321. return rsa_tests();
  322. }
  323. if (mode_sv == "bigint") {
  324. return bigint_tests();
  325. }
  326. if (mode_sv == "tls") {
  327. if (run_tests)
  328. return tls_tests();
  329. return run(tls);
  330. }
  331. if (mode_sv == "test") {
  332. encrypting = true;
  333. aes_cbc_tests();
  334. encrypting = false;
  335. aes_cbc_tests();
  336. md5_tests();
  337. sha1_tests();
  338. sha256_tests();
  339. sha512_tests();
  340. hmac_md5_tests();
  341. hmac_sha256_tests();
  342. hmac_sha512_tests();
  343. rsa_tests();
  344. tls_tests();
  345. bigint_tests();
  346. return 0;
  347. }
  348. encrypting = mode_sv == "encrypt";
  349. if (encrypting || mode_sv == "decrypt") {
  350. if (suite == nullptr)
  351. suite = DEFAULT_CIPHER_SUITE;
  352. StringView suite_sv { suite };
  353. if (StringView(suite) == "AES_CBC") {
  354. if (run_tests)
  355. return aes_cbc_tests();
  356. if (!Crypto::Cipher::AESCipher::KeyType::is_valid_key_size(key_bits)) {
  357. printf("Invalid key size for AES: %d\n", key_bits);
  358. return 1;
  359. }
  360. if (strlen(secret_key) != (size_t)key_bits / 8) {
  361. printf("Key must be exactly %d bytes long\n", key_bits / 8);
  362. return 1;
  363. }
  364. return run(aes_cbc);
  365. } else {
  366. printf("Unknown cipher suite '%s'\n", suite);
  367. return 1;
  368. }
  369. }
  370. printf("Unknown mode '%s', check out the list of modes\n", mode);
  371. return 1;
  372. }
  373. #define I_TEST(thing) \
  374. { \
  375. printf("Testing " #thing "... "); \
  376. fflush(stdout); \
  377. gettimeofday(&start_time, &tz); \
  378. }
  379. #define PASS \
  380. { \
  381. struct timeval end_time { \
  382. 0, 0 \
  383. }; \
  384. gettimeofday(&end_time, &tz); \
  385. time_t interval_s = end_time.tv_sec - start_time.tv_sec; \
  386. suseconds_t interval_us = end_time.tv_usec; \
  387. if (interval_us < start_time.tv_usec) { \
  388. interval_s -= 1; \
  389. interval_us += 1000000; \
  390. } \
  391. interval_us -= start_time.tv_usec; \
  392. printf("PASS %llds %dus\n", interval_s, interval_us); \
  393. }
  394. #define FAIL(reason) printf("FAIL: " #reason "\n")
  395. ByteBuffer operator""_b(const char* string, size_t length)
  396. {
  397. dbg() << "Create byte buffer of size " << length;
  398. return ByteBuffer::copy(string, length);
  399. }
  400. // tests go after here
  401. // please be reasonable with orders kthx
  402. void aes_cbc_test_name();
  403. void aes_cbc_test_encrypt();
  404. void aes_cbc_test_decrypt();
  405. void md5_test_name();
  406. void md5_test_hash();
  407. void md5_test_consecutive_updates();
  408. void sha1_test_name();
  409. void sha1_test_hash();
  410. void sha256_test_name();
  411. void sha256_test_hash();
  412. void sha512_test_name();
  413. void sha512_test_hash();
  414. void hmac_md5_test_name();
  415. void hmac_md5_test_process();
  416. void hmac_sha256_test_name();
  417. void hmac_sha256_test_process();
  418. void hmac_sha512_test_name();
  419. void hmac_sha512_test_process();
  420. void rsa_test_encrypt();
  421. void rsa_test_der_parse();
  422. void rsa_test_encrypt_decrypt();
  423. void rsa_emsa_pss_test_create();
  424. void bigint_test_number_theory(); // FIXME: we should really move these num theory stuff out
  425. void tls_test_client_hello();
  426. void bigint_test_fibo500();
  427. void bigint_addition_edgecases();
  428. void bigint_subtraction();
  429. void bigint_multiplication();
  430. void bigint_division();
  431. void bigint_base10();
  432. void bigint_import_export();
  433. int aes_cbc_tests()
  434. {
  435. aes_cbc_test_name();
  436. if (encrypting) {
  437. aes_cbc_test_encrypt();
  438. } else {
  439. aes_cbc_test_decrypt();
  440. }
  441. return 0;
  442. }
  443. void aes_cbc_test_name()
  444. {
  445. I_TEST((AES CBC class name));
  446. Crypto::Cipher::AESCipher::CBCMode cipher("WellHelloFriends"_b, 128, Crypto::Cipher::Intent::Encryption);
  447. if (cipher.class_name() != "AES_CBC")
  448. FAIL(Invalid class name);
  449. else
  450. PASS;
  451. }
  452. void aes_cbc_test_encrypt()
  453. {
  454. auto test_it = [](auto& cipher, auto& result) {
  455. auto in = "This is a test! This is another test!"_b;
  456. auto out = cipher.create_aligned_buffer(in.size());
  457. auto iv = ByteBuffer::create_zeroed(Crypto::Cipher::AESCipher::block_size());
  458. cipher.encrypt(in, out, iv);
  459. if (out.size() != sizeof(result))
  460. FAIL(size mismatch);
  461. else if (memcmp(out.data(), result, out.size()) != 0) {
  462. FAIL(invalid data);
  463. print_buffer(out, Crypto::Cipher::AESCipher::block_size());
  464. } else
  465. PASS;
  466. };
  467. {
  468. I_TEST((AES CBC with 128 bit key | Encrypt))
  469. u8 result[] {
  470. 0xb8, 0x06, 0x7c, 0xf2, 0xa9, 0x56, 0x63, 0x58, 0x2d, 0x5c, 0xa1, 0x4b, 0xc5, 0xe3, 0x08,
  471. 0xcf, 0xb5, 0x93, 0xfb, 0x67, 0xb6, 0xf7, 0xaf, 0x45, 0x34, 0x64, 0x70, 0x9e, 0xc9, 0x1a,
  472. 0x8b, 0xd3, 0x70, 0x45, 0xf0, 0x79, 0x65, 0xca, 0xb9, 0x03, 0x88, 0x72, 0x1c, 0xdd, 0xab,
  473. 0x45, 0x6b, 0x1c
  474. };
  475. Crypto::Cipher::AESCipher::CBCMode cipher("WellHelloFriends"_b, 128, Crypto::Cipher::Intent::Encryption);
  476. test_it(cipher, result);
  477. }
  478. {
  479. I_TEST((AES CBC with 192 bit key | Encrypt))
  480. u8 result[] {
  481. 0xae, 0xd2, 0x70, 0xc4, 0x9c, 0xaa, 0x83, 0x33, 0xd3, 0xd3, 0xac, 0x11, 0x65, 0x35, 0xf7,
  482. 0x19, 0x48, 0x7c, 0x7a, 0x8a, 0x95, 0x64, 0xe7, 0xc6, 0x0a, 0xdf, 0x10, 0x06, 0xdc, 0x90,
  483. 0x68, 0x51, 0x09, 0xd7, 0x3b, 0x48, 0x1b, 0x8a, 0xd3, 0x50, 0x09, 0xba, 0xfc, 0xde, 0x11,
  484. 0xe0, 0x3f, 0xcb
  485. };
  486. Crypto::Cipher::AESCipher::CBCMode cipher("Well Hello Friends! whf!"_b, 192, Crypto::Cipher::Intent::Encryption);
  487. test_it(cipher, result);
  488. }
  489. {
  490. I_TEST((AES CBC with 256 bit key | Encrypt))
  491. u8 result[] {
  492. 0x0a, 0x44, 0x4d, 0x62, 0x9e, 0x8b, 0xd8, 0x11, 0x80, 0x48, 0x2a, 0x32, 0x53, 0x61, 0xe7,
  493. 0x59, 0x62, 0x55, 0x9e, 0xf4, 0xe6, 0xad, 0xea, 0xc5, 0x0b, 0xf6, 0xbc, 0x6a, 0xcb, 0x9c,
  494. 0x47, 0x9f, 0xc2, 0x21, 0xe6, 0x19, 0x62, 0xc3, 0x75, 0xca, 0xab, 0x2d, 0x18, 0xa1, 0x54,
  495. 0xd1, 0x41, 0xe6
  496. };
  497. Crypto::Cipher::AESCipher::CBCMode cipher("WellHelloFriendsWellHelloFriends"_b, 256, Crypto::Cipher::Intent::Encryption);
  498. test_it(cipher, result);
  499. }
  500. {
  501. I_TEST((AES CBC with 256 bit key | Encrypt with unsigned key))
  502. u8 result[] {
  503. 0x18, 0x71, 0x80, 0x4c, 0x28, 0x07, 0x55, 0x3c, 0x05, 0x33, 0x36, 0x3f, 0x19, 0x38, 0x5c,
  504. 0xbe, 0xf8, 0xb8, 0x0e, 0x0e, 0x66, 0x67, 0x63, 0x9c, 0xbf, 0x73, 0xcd, 0x82, 0xf9, 0xcb,
  505. 0x9d, 0x81, 0x56, 0xc6, 0x75, 0x14, 0x8b, 0x79, 0x60, 0xb0, 0xdf, 0xaa, 0x2c, 0x2b, 0xd4,
  506. 0xd6, 0xa0, 0x46
  507. };
  508. u8 key[] { 0x0a, 0x8c, 0x5b, 0x0d, 0x8a, 0x68, 0x43, 0xf7, 0xaf, 0xc0, 0xe3, 0x4e, 0x4b, 0x43, 0xaa, 0x28, 0x69, 0x9b, 0x6f, 0xe7, 0x24, 0x82, 0x1c, 0x71, 0x86, 0xf6, 0x2b, 0x87, 0xd6, 0x8b, 0x8f, 0xf1 };
  509. Crypto::Cipher::AESCipher::CBCMode cipher(ByteBuffer::wrap(key, 32), 256, Crypto::Cipher::Intent::Encryption);
  510. test_it(cipher, result);
  511. }
  512. // TODO: Test non-CMS padding options
  513. }
  514. void aes_cbc_test_decrypt()
  515. {
  516. auto test_it = [](auto& cipher, auto& result, auto result_len) {
  517. auto true_value = "This is a test! This is another test!";
  518. auto in = ByteBuffer::copy(result, result_len);
  519. auto out = cipher.create_aligned_buffer(in.size());
  520. auto iv = ByteBuffer::create_zeroed(Crypto::Cipher::AESCipher::block_size());
  521. cipher.decrypt(in, out, iv);
  522. if (out.size() != strlen(true_value)) {
  523. FAIL(size mismatch);
  524. printf("Expected %zu bytes but got %zu\n", strlen(true_value), out.size());
  525. } else if (memcmp(out.data(), true_value, strlen(true_value)) != 0) {
  526. FAIL(invalid data);
  527. print_buffer(out, Crypto::Cipher::AESCipher::block_size());
  528. } else
  529. PASS;
  530. };
  531. {
  532. I_TEST((AES CBC with 128 bit key | Decrypt))
  533. u8 result[] {
  534. 0xb8, 0x06, 0x7c, 0xf2, 0xa9, 0x56, 0x63, 0x58, 0x2d, 0x5c, 0xa1, 0x4b, 0xc5, 0xe3, 0x08,
  535. 0xcf, 0xb5, 0x93, 0xfb, 0x67, 0xb6, 0xf7, 0xaf, 0x45, 0x34, 0x64, 0x70, 0x9e, 0xc9, 0x1a,
  536. 0x8b, 0xd3, 0x70, 0x45, 0xf0, 0x79, 0x65, 0xca, 0xb9, 0x03, 0x88, 0x72, 0x1c, 0xdd, 0xab,
  537. 0x45, 0x6b, 0x1c
  538. };
  539. Crypto::Cipher::AESCipher::CBCMode cipher("WellHelloFriends"_b, 128, Crypto::Cipher::Intent::Decryption);
  540. test_it(cipher, result, 48);
  541. }
  542. {
  543. I_TEST((AES CBC with 192 bit key | Decrypt))
  544. u8 result[] {
  545. 0xae, 0xd2, 0x70, 0xc4, 0x9c, 0xaa, 0x83, 0x33, 0xd3, 0xd3, 0xac, 0x11, 0x65, 0x35, 0xf7,
  546. 0x19, 0x48, 0x7c, 0x7a, 0x8a, 0x95, 0x64, 0xe7, 0xc6, 0x0a, 0xdf, 0x10, 0x06, 0xdc, 0x90,
  547. 0x68, 0x51, 0x09, 0xd7, 0x3b, 0x48, 0x1b, 0x8a, 0xd3, 0x50, 0x09, 0xba, 0xfc, 0xde, 0x11,
  548. 0xe0, 0x3f, 0xcb
  549. };
  550. Crypto::Cipher::AESCipher::CBCMode cipher("Well Hello Friends! whf!"_b, 192, Crypto::Cipher::Intent::Decryption);
  551. test_it(cipher, result, 48);
  552. }
  553. {
  554. I_TEST((AES CBC with 256 bit key | Decrypt))
  555. u8 result[] {
  556. 0x0a, 0x44, 0x4d, 0x62, 0x9e, 0x8b, 0xd8, 0x11, 0x80, 0x48, 0x2a, 0x32, 0x53, 0x61, 0xe7,
  557. 0x59, 0x62, 0x55, 0x9e, 0xf4, 0xe6, 0xad, 0xea, 0xc5, 0x0b, 0xf6, 0xbc, 0x6a, 0xcb, 0x9c,
  558. 0x47, 0x9f, 0xc2, 0x21, 0xe6, 0x19, 0x62, 0xc3, 0x75, 0xca, 0xab, 0x2d, 0x18, 0xa1, 0x54,
  559. 0xd1, 0x41, 0xe6
  560. };
  561. Crypto::Cipher::AESCipher::CBCMode cipher("WellHelloFriendsWellHelloFriends"_b, 256, Crypto::Cipher::Intent::Decryption);
  562. test_it(cipher, result, 48);
  563. }
  564. // TODO: Test non-CMS padding options
  565. }
  566. int md5_tests()
  567. {
  568. md5_test_name();
  569. md5_test_hash();
  570. md5_test_consecutive_updates();
  571. return 0;
  572. }
  573. void md5_test_name()
  574. {
  575. I_TEST((MD5 class name));
  576. Crypto::Hash::MD5 md5;
  577. if (md5.class_name() != "MD5")
  578. FAIL(Invalid class name);
  579. else
  580. PASS;
  581. }
  582. void md5_test_hash()
  583. {
  584. {
  585. I_TEST((MD5 Hashing | "Well hello friends"));
  586. u8 result[] {
  587. 0xaf, 0x04, 0x3a, 0x08, 0x94, 0x38, 0x6e, 0x7f, 0xbf, 0x73, 0xe4, 0xaa, 0xf0, 0x8e, 0xee, 0x4c
  588. };
  589. auto digest = Crypto::Hash::MD5::hash("Well hello friends");
  590. if (memcmp(result, digest.data, Crypto::Hash::MD5::digest_size()) != 0) {
  591. FAIL(Invalid hash);
  592. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::MD5::digest_size()), -1);
  593. } else {
  594. PASS;
  595. }
  596. }
  597. // RFC tests
  598. {
  599. I_TEST((MD5 Hashing | ""));
  600. u8 result[] {
  601. 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
  602. };
  603. auto digest = Crypto::Hash::MD5::hash("");
  604. if (memcmp(result, digest.data, Crypto::Hash::MD5::digest_size()) != 0) {
  605. FAIL(Invalid hash);
  606. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::MD5::digest_size()), -1);
  607. } else {
  608. PASS;
  609. }
  610. }
  611. {
  612. I_TEST((MD5 Hashing | "a"));
  613. u8 result[] {
  614. 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61
  615. };
  616. auto digest = Crypto::Hash::MD5::hash("a");
  617. if (memcmp(result, digest.data, Crypto::Hash::MD5::digest_size()) != 0) {
  618. FAIL(Invalid hash);
  619. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::MD5::digest_size()), -1);
  620. } else {
  621. PASS;
  622. }
  623. }
  624. {
  625. I_TEST((MD5 Hashing | "abcdefghijklmnopqrstuvwxyz"));
  626. u8 result[] {
  627. 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b
  628. };
  629. auto digest = Crypto::Hash::MD5::hash("abcdefghijklmnopqrstuvwxyz");
  630. if (memcmp(result, digest.data, Crypto::Hash::MD5::digest_size()) != 0) {
  631. FAIL(Invalid hash);
  632. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::MD5::digest_size()), -1);
  633. } else {
  634. PASS;
  635. }
  636. }
  637. {
  638. I_TEST((MD5 Hashing | Long Sequence));
  639. u8 result[] {
  640. 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a
  641. };
  642. auto digest = Crypto::Hash::MD5::hash("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
  643. if (memcmp(result, digest.data, Crypto::Hash::MD5::digest_size()) != 0) {
  644. FAIL(Invalid hash);
  645. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::MD5::digest_size()), -1);
  646. } else {
  647. PASS;
  648. }
  649. }
  650. }
  651. void md5_test_consecutive_updates()
  652. {
  653. {
  654. I_TEST((MD5 Hashing | Multiple Updates));
  655. u8 result[] {
  656. 0xaf, 0x04, 0x3a, 0x08, 0x94, 0x38, 0x6e, 0x7f, 0xbf, 0x73, 0xe4, 0xaa, 0xf0, 0x8e, 0xee, 0x4c
  657. };
  658. Crypto::Hash::MD5 md5;
  659. md5.update("Well");
  660. md5.update(" hello ");
  661. md5.update("friends");
  662. auto digest = md5.digest();
  663. if (memcmp(result, digest.data, Crypto::Hash::MD5::digest_size()) != 0)
  664. FAIL(Invalid hash);
  665. else
  666. PASS;
  667. }
  668. {
  669. I_TEST((MD5 Hashing | Reuse));
  670. Crypto::Hash::MD5 md5;
  671. md5.update("Well");
  672. md5.update(" hello ");
  673. md5.update("friends");
  674. auto digest0 = md5.digest();
  675. md5.update("Well");
  676. md5.update(" hello ");
  677. md5.update("friends");
  678. auto digest1 = md5.digest();
  679. if (memcmp(digest0.data, digest1.data, Crypto::Hash::MD5::digest_size()) != 0)
  680. FAIL(Cannot reuse);
  681. else
  682. PASS;
  683. }
  684. }
  685. int hmac_md5_tests()
  686. {
  687. hmac_md5_test_name();
  688. hmac_md5_test_process();
  689. return 0;
  690. }
  691. int hmac_sha256_tests()
  692. {
  693. hmac_sha256_test_name();
  694. hmac_sha256_test_process();
  695. return 0;
  696. }
  697. int hmac_sha512_tests()
  698. {
  699. hmac_sha512_test_name();
  700. hmac_sha512_test_process();
  701. return 0;
  702. }
  703. void hmac_md5_test_name()
  704. {
  705. I_TEST((HMAC - MD5 | Class name));
  706. Crypto::Authentication::HMAC<Crypto::Hash::MD5> hmac("Well Hello Friends");
  707. if (hmac.class_name() != "HMAC-MD5")
  708. FAIL(Invalid class name);
  709. else
  710. PASS;
  711. }
  712. void hmac_md5_test_process()
  713. {
  714. {
  715. I_TEST((HMAC - MD5 | Basic));
  716. Crypto::Authentication::HMAC<Crypto::Hash::MD5> hmac("Well Hello Friends");
  717. u8 result[] {
  718. 0x3b, 0x5b, 0xde, 0x30, 0x3a, 0x54, 0x7b, 0xbb, 0x09, 0xfe, 0x78, 0x89, 0xbc, 0x9f, 0x22, 0xa3
  719. };
  720. auto mac = hmac.process("Some bogus data");
  721. if (memcmp(result, mac.data, hmac.digest_size()) != 0) {
  722. FAIL(Invalid mac);
  723. print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
  724. } else
  725. PASS;
  726. }
  727. {
  728. I_TEST((HMAC - MD5 | Reuse));
  729. Crypto::Authentication::HMAC<Crypto::Hash::MD5> hmac("Well Hello Friends");
  730. auto mac_0 = hmac.process("Some bogus data");
  731. auto mac_1 = hmac.process("Some bogus data");
  732. if (memcmp(mac_0.data, mac_1.data, hmac.digest_size()) != 0) {
  733. FAIL(Cannot reuse);
  734. } else
  735. PASS;
  736. }
  737. }
  738. int sha1_tests()
  739. {
  740. sha1_test_name();
  741. sha1_test_hash();
  742. return 0;
  743. }
  744. void sha1_test_name()
  745. {
  746. I_TEST((SHA1 class name));
  747. Crypto::Hash::SHA1 sha;
  748. if (sha.class_name() != "SHA1") {
  749. FAIL(Invalid class name);
  750. printf("%s\n", sha.class_name().characters());
  751. } else
  752. PASS;
  753. }
  754. void sha1_test_hash()
  755. {
  756. {
  757. I_TEST((SHA256 Hashing | ""));
  758. u8 result[] {
  759. 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
  760. };
  761. auto digest = Crypto::Hash::SHA1::hash("");
  762. if (memcmp(result, digest.data, Crypto::Hash::SHA1::digest_size()) != 0) {
  763. FAIL(Invalid hash);
  764. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA1::digest_size()), -1);
  765. } else
  766. PASS;
  767. }
  768. {
  769. I_TEST((SHA256 Hashing | Long String));
  770. u8 result[] {
  771. 0x12, 0x15, 0x1f, 0xb1, 0x04, 0x44, 0x93, 0xcc, 0xed, 0x54, 0xa6, 0xb8, 0x7e, 0x93, 0x37, 0x7b, 0xb2, 0x13, 0x39, 0xdb
  772. };
  773. auto digest = Crypto::Hash::SHA1::hash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  774. if (memcmp(result, digest.data, Crypto::Hash::SHA1::digest_size()) != 0) {
  775. FAIL(Invalid hash);
  776. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA1::digest_size()), -1);
  777. } else
  778. PASS;
  779. }
  780. {
  781. I_TEST((SHA256 Hashing | Successive Updates));
  782. u8 result[] {
  783. 0xd6, 0x6e, 0xce, 0xd1, 0xf4, 0x08, 0xc6, 0xd8, 0x35, 0xab, 0xf0, 0xc9, 0x05, 0x26, 0xa4, 0xb2, 0xb8, 0xa3, 0x7c, 0xd3
  784. };
  785. auto hasher = Crypto::Hash::SHA1 {};
  786. hasher.update("aaaaaaaaaaaaaaa");
  787. hasher.update("aaaaaaaaaaaaaaa");
  788. hasher.update("aaaaaaaaaaaaaaa");
  789. hasher.update("aaaaaaaaaaaaaaa");
  790. hasher.update("aaaaaaaaaaaaaaa");
  791. hasher.update("aaaaaaaaaaaaaaa");
  792. hasher.update("aaaaaaaaaaaaaaa");
  793. hasher.update("aaaaaaaaaaaaaaa");
  794. hasher.update("aaaaaaaaaaaaaaa");
  795. hasher.update("aaaaaaaaaaaaaaa");
  796. hasher.update("aaaaaaaaaaaaaaa");
  797. hasher.update("aaaaaaaaaaaaaaa");
  798. hasher.update("aaaaaaaaa");
  799. auto digest = hasher.digest();
  800. if (memcmp(result, digest.data, Crypto::Hash::SHA1::digest_size()) != 0) {
  801. FAIL(Invalid hash);
  802. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA1::digest_size()), -1);
  803. } else
  804. PASS;
  805. }
  806. }
  807. int sha256_tests()
  808. {
  809. sha256_test_name();
  810. sha256_test_hash();
  811. return 0;
  812. }
  813. void sha256_test_name()
  814. {
  815. I_TEST((SHA256 class name));
  816. Crypto::Hash::SHA256 sha;
  817. if (sha.class_name() != "SHA256") {
  818. FAIL(Invalid class name);
  819. printf("%s\n", sha.class_name().characters());
  820. } else
  821. PASS;
  822. }
  823. void sha256_test_hash()
  824. {
  825. {
  826. I_TEST((SHA256 Hashing | "Well hello friends"));
  827. u8 result[] {
  828. 0x9a, 0xcd, 0x50, 0xf9, 0xa2, 0xaf, 0x37, 0xe4, 0x71, 0xf7, 0x61, 0xc3, 0xfe, 0x7b, 0x8d, 0xea, 0x56, 0x17, 0xe5, 0x1d, 0xac, 0x80, 0x2f, 0xe6, 0xc1, 0x77, 0xb7, 0x4a, 0xbf, 0x0a, 0xbb, 0x5a
  829. };
  830. auto digest = Crypto::Hash::SHA256::hash("Well hello friends");
  831. if (memcmp(result, digest.data, Crypto::Hash::SHA256::digest_size()) != 0) {
  832. FAIL(Invalid hash);
  833. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA256::digest_size()), -1);
  834. } else
  835. PASS;
  836. }
  837. {
  838. I_TEST((SHA256 Hashing | ""));
  839. u8 result[] {
  840. 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
  841. };
  842. auto digest = Crypto::Hash::SHA256::hash("");
  843. if (memcmp(result, digest.data, Crypto::Hash::SHA256::digest_size()) != 0) {
  844. FAIL(Invalid hash);
  845. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA256::digest_size()), -1);
  846. } else
  847. PASS;
  848. }
  849. }
  850. void hmac_sha256_test_name()
  851. {
  852. I_TEST((HMAC - SHA256 | Class name));
  853. Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac("Well Hello Friends");
  854. if (hmac.class_name() != "HMAC-SHA256")
  855. FAIL(Invalid class name);
  856. else
  857. PASS;
  858. }
  859. void hmac_sha256_test_process()
  860. {
  861. {
  862. I_TEST((HMAC - SHA256 | Basic));
  863. Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac("Well Hello Friends");
  864. u8 result[] {
  865. 0x1a, 0xf2, 0x20, 0x62, 0xde, 0x3b, 0x84, 0x65, 0xc1, 0x25, 0x23, 0x99, 0x76, 0x15, 0x1b, 0xec, 0x15, 0x21, 0x82, 0x1f, 0x23, 0xca, 0x11, 0x66, 0xdd, 0x8c, 0x6e, 0xf1, 0x81, 0x3b, 0x7f, 0x1b
  866. };
  867. auto mac = hmac.process("Some bogus data");
  868. if (memcmp(result, mac.data, hmac.digest_size()) != 0) {
  869. FAIL(Invalid mac);
  870. print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
  871. } else
  872. PASS;
  873. }
  874. {
  875. I_TEST((HMAC - SHA256 | Reuse));
  876. Crypto::Authentication::HMAC<Crypto::Hash::SHA256> hmac("Well Hello Friends");
  877. auto mac_0 = hmac.process("Some bogus data");
  878. auto mac_1 = hmac.process("Some bogus data");
  879. if (memcmp(mac_0.data, mac_1.data, hmac.digest_size()) != 0) {
  880. FAIL(Cannot reuse);
  881. } else
  882. PASS;
  883. }
  884. }
  885. int sha512_tests()
  886. {
  887. sha512_test_name();
  888. sha512_test_hash();
  889. return 0;
  890. }
  891. void sha512_test_name()
  892. {
  893. I_TEST((SHA512 class name));
  894. Crypto::Hash::SHA512 sha;
  895. if (sha.class_name() != "SHA512") {
  896. FAIL(Invalid class name);
  897. printf("%s\n", sha.class_name().characters());
  898. } else
  899. PASS;
  900. }
  901. void sha512_test_hash()
  902. {
  903. {
  904. I_TEST((SHA512 Hashing | "Well hello friends"));
  905. u8 result[] {
  906. 0x00, 0xfe, 0x68, 0x09, 0x71, 0x0e, 0xcb, 0x2b, 0xe9, 0x58, 0x00, 0x13, 0x69, 0x6a, 0x9e, 0x9e, 0xbd, 0x09, 0x1b, 0xfe, 0x14, 0xc9, 0x13, 0x82, 0xc7, 0x40, 0x34, 0xfe, 0xca, 0xe6, 0x87, 0xcb, 0x26, 0x36, 0x92, 0xe6, 0x34, 0x94, 0x3a, 0x11, 0xe5, 0xbb, 0xb5, 0xeb, 0x8e, 0x70, 0xef, 0x64, 0xca, 0xf7, 0x21, 0xb1, 0xde, 0xf2, 0x34, 0x85, 0x6f, 0xa8, 0x56, 0xd8, 0x23, 0xa1, 0x3b, 0x29
  907. };
  908. auto digest = Crypto::Hash::SHA512::hash("Well hello friends");
  909. if (memcmp(result, digest.data, Crypto::Hash::SHA512::digest_size()) != 0) {
  910. FAIL(Invalid hash);
  911. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA512::digest_size()), -1);
  912. } else
  913. PASS;
  914. }
  915. {
  916. I_TEST((SHA512 Hashing | ""));
  917. u8 result[] {
  918. 0xcf, 0x83, 0xe1, 0x35, 0x7e, 0xef, 0xb8, 0xbd, 0xf1, 0x54, 0x28, 0x50, 0xd6, 0x6d, 0x80, 0x07, 0xd6, 0x20, 0xe4, 0x05, 0x0b, 0x57, 0x15, 0xdc, 0x83, 0xf4, 0xa9, 0x21, 0xd3, 0x6c, 0xe9, 0xce, 0x47, 0xd0, 0xd1, 0x3c, 0x5d, 0x85, 0xf2, 0xb0, 0xff, 0x83, 0x18, 0xd2, 0x87, 0x7e, 0xec, 0x2f, 0x63, 0xb9, 0x31, 0xbd, 0x47, 0x41, 0x7a, 0x81, 0xa5, 0x38, 0x32, 0x7a, 0xf9, 0x27, 0xda, 0x3e
  919. };
  920. auto digest = Crypto::Hash::SHA512::hash("");
  921. if (memcmp(result, digest.data, Crypto::Hash::SHA512::digest_size()) != 0) {
  922. FAIL(Invalid hash);
  923. print_buffer(ByteBuffer::wrap(digest.data, Crypto::Hash::SHA512::digest_size()), -1);
  924. } else
  925. PASS;
  926. }
  927. }
  928. void hmac_sha512_test_name()
  929. {
  930. I_TEST((HMAC - SHA512 | Class name));
  931. Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac("Well Hello Friends");
  932. if (hmac.class_name() != "HMAC-SHA512")
  933. FAIL(Invalid class name);
  934. else
  935. PASS;
  936. }
  937. void hmac_sha512_test_process()
  938. {
  939. {
  940. I_TEST((HMAC - SHA512 | Basic));
  941. Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac("Well Hello Friends");
  942. u8 result[] {
  943. 0xeb, 0xa8, 0x34, 0x11, 0xfd, 0x5b, 0x46, 0x5b, 0xef, 0xbb, 0x67, 0x5e, 0x7d, 0xc2, 0x7c, 0x2c, 0x6b, 0xe1, 0xcf, 0xe6, 0xc7, 0xe4, 0x7d, 0xeb, 0xca, 0x97, 0xb7, 0x4c, 0xd3, 0x4d, 0x6f, 0x08, 0x9f, 0x0d, 0x3a, 0xf1, 0xcb, 0x00, 0x79, 0x78, 0x2f, 0x05, 0x8e, 0xeb, 0x94, 0x48, 0x0d, 0x50, 0x64, 0x3b, 0xca, 0x70, 0xe2, 0x69, 0x38, 0x4f, 0xe4, 0xb0, 0x49, 0x0f, 0xc5, 0x4c, 0x7a, 0xa7
  944. };
  945. auto mac = hmac.process("Some bogus data");
  946. if (memcmp(result, mac.data, hmac.digest_size()) != 0) {
  947. FAIL(Invalid mac);
  948. print_buffer(ByteBuffer::wrap(mac.data, hmac.digest_size()), -1);
  949. } else
  950. PASS;
  951. }
  952. {
  953. I_TEST((HMAC - SHA512 | Reuse));
  954. Crypto::Authentication::HMAC<Crypto::Hash::SHA512> hmac("Well Hello Friends");
  955. auto mac_0 = hmac.process("Some bogus data");
  956. auto mac_1 = hmac.process("Some bogus data");
  957. if (memcmp(mac_0.data, mac_1.data, hmac.digest_size()) != 0) {
  958. FAIL(Cannot reuse);
  959. } else
  960. PASS;
  961. }
  962. }
  963. int rsa_tests()
  964. {
  965. rsa_test_encrypt();
  966. rsa_test_der_parse();
  967. bigint_test_number_theory();
  968. rsa_test_encrypt_decrypt();
  969. rsa_emsa_pss_test_create();
  970. return 0;
  971. }
  972. void rsa_test_encrypt()
  973. {
  974. {
  975. I_TEST((RSA RAW | Encryption));
  976. ByteBuffer data { "hellohellohellohellohellohellohellohellohellohellohellohello123-"_b };
  977. u8 result[] { 0x6f, 0x7b, 0xe2, 0xd3, 0x95, 0xf8, 0x8d, 0x87, 0x6d, 0x10, 0x5e, 0xc3, 0xcd, 0xf7, 0xbb, 0xa6, 0x62, 0x8e, 0x45, 0xa0, 0xf1, 0xe5, 0x0f, 0xdf, 0x69, 0xcb, 0xb6, 0xd5, 0x42, 0x06, 0x7d, 0x72, 0xa9, 0x5e, 0xae, 0xbf, 0xbf, 0x0f, 0xe0, 0xeb, 0x31, 0x31, 0xca, 0x8a, 0x81, 0x1e, 0xb9, 0xec, 0x6d, 0xcc, 0xb8, 0xa4, 0xac, 0xa3, 0x31, 0x05, 0xa9, 0xac, 0xc9, 0xd3, 0xe6, 0x2a, 0x18, 0xfe };
  978. Crypto::PK::RSA rsa(
  979. "8126832723025844890518845777858816391166654950553329127845898924164623511718747856014227624997335860970996746552094406240834082304784428582653994490504519"_bigint,
  980. "4234603516465654167360850580101327813936403862038934287300450163438938741499875303761385527882335478349599685406941909381269804396099893549838642251053393"_bigint,
  981. "65537"_bigint);
  982. u8 buffer[rsa.output_size()];
  983. auto buf = ByteBuffer::wrap(buffer, sizeof(buffer));
  984. rsa.encrypt(data, buf);
  985. if (memcmp(result, buf.data(), buf.size())) {
  986. FAIL(Invalid encryption result);
  987. print_buffer(buf, 16);
  988. } else {
  989. PASS;
  990. }
  991. }
  992. {
  993. I_TEST((RSA PKCS #1 1.5 | Encryption));
  994. ByteBuffer data { "hellohellohellohellohellohellohellohellohello123-"_b };
  995. Crypto::PK::RSA_PKCS1_EME rsa(
  996. "8126832723025844890518845777858816391166654950553329127845898924164623511718747856014227624997335860970996746552094406240834082304784428582653994490504519"_bigint,
  997. "4234603516465654167360850580101327813936403862038934287300450163438938741499875303761385527882335478349599685406941909381269804396099893549838642251053393"_bigint,
  998. "65537"_bigint);
  999. u8 buffer[rsa.output_size()];
  1000. auto buf = ByteBuffer::wrap(buffer, sizeof(buffer));
  1001. rsa.encrypt(data, buf);
  1002. rsa.decrypt(buf, buf);
  1003. if (memcmp(buf.data(), "hellohellohellohellohellohellohellohellohello123-", 49))
  1004. FAIL(Invalid encryption);
  1005. else {
  1006. dbg() << "out size " << buf.size() << " values: " << StringView { (char*)buf.data(), buf.size() };
  1007. PASS;
  1008. }
  1009. }
  1010. }
  1011. void bigint_test_number_theory()
  1012. {
  1013. {
  1014. I_TEST((Number Theory | Modular Inverse));
  1015. if (Crypto::NumberTheory::ModularInverse(7, 87) == 25) {
  1016. PASS;
  1017. } else {
  1018. FAIL(Invalid result);
  1019. }
  1020. }
  1021. {
  1022. I_TEST((Number Theory | Modular Power));
  1023. auto exp = Crypto::NumberTheory::ModularPower(
  1024. Crypto::UnsignedBigInteger::from_base10("2988348162058574136915891421498819466320163312926952423791023078876139"),
  1025. Crypto::UnsignedBigInteger::from_base10("2351399303373464486466122544523690094744975233415544072992656881240319"),
  1026. 10000);
  1027. if (exp == 3059) {
  1028. PASS;
  1029. } else {
  1030. FAIL(Invalid result);
  1031. puts(exp.to_base10().characters());
  1032. }
  1033. }
  1034. }
  1035. void rsa_emsa_pss_test_create()
  1036. {
  1037. {
  1038. // This is a template validity test
  1039. I_TEST((RSA EMSA_PSS | Construction));
  1040. Crypto::PK::RSA rsa;
  1041. Crypto::PK::RSA_EMSA_PSS<Crypto::Hash::SHA256> rsa_esma_pss(rsa);
  1042. PASS;
  1043. }
  1044. }
  1045. void rsa_test_der_parse()
  1046. {
  1047. I_TEST((RSA | ASN1 DER / PEM encoded Key import));
  1048. auto privkey = R"(-----BEGIN RSA PRIVATE KEY-----
  1049. MIIBOgIBAAJBAJsrIYHxs1YL9tpfodaWs1lJoMdF4kgFisUFSj6nvBhJUlmBh607AlgTaX0E
  1050. DGPYycXYGZ2n6rqmms5lpDXBpUcCAwEAAQJAUNpPkmtEHDENxsoQBUXvXDYeXdePSiIBJhpU
  1051. joNOYoR5R9z5oX2cpcyykQ58FC2vKKg+x8N6xczG7qO95tw5UQIhAN354CP/FA+uTeJ6KJ+i
  1052. zCBCl58CjNCzO0s5HTc56el5AiEAsvPKXo5/9gS/S4UzDRP6abq7GreixTfjR8LXidk3FL8C
  1053. IQCTjYI861Y+hjMnlORkGSdvWlTHUj6gjEOh4TlWeJzQoQIgAxMZOQKtxCZUuxFwzRq4xLRG
  1054. nrDlBQpuxz7bwSyQO7UCIHrYMnDohgNbwtA5ZpW3H1cKKQQvueWm6sxW9P5sUrZ3
  1055. -----END RSA PRIVATE KEY-----)";
  1056. Crypto::PK::RSA rsa(privkey);
  1057. if (rsa.public_key().public_exponent() == 65537) {
  1058. if (rsa.private_key().private_exponent() == "4234603516465654167360850580101327813936403862038934287300450163438938741499875303761385527882335478349599685406941909381269804396099893549838642251053393"_bigint) {
  1059. PASS;
  1060. } else
  1061. FAIL(Invalid private exponent);
  1062. } else {
  1063. FAIL(Invalid public exponent);
  1064. }
  1065. }
  1066. void rsa_test_encrypt_decrypt()
  1067. {
  1068. I_TEST((RSA | Encrypt));
  1069. dbg() << " creating rsa object";
  1070. Crypto::PK::RSA rsa(
  1071. "9527497237087650398000977129550904920919162360737979403539302312977329868395261515707123424679295515888026193056908173564681660256268221509339074678416049"_bigint,
  1072. "39542231845947188736992321577701849924317746648774438832456325878966594812143638244746284968851807975097653255909707366086606867657273809465195392910913"_bigint,
  1073. "65537"_bigint);
  1074. dbg() << "Output size: " << rsa.output_size();
  1075. auto dec = ByteBuffer::create_zeroed(rsa.output_size());
  1076. auto enc = ByteBuffer::create_zeroed(rsa.output_size());
  1077. enc.overwrite(0, "WellHelloFriendsWellHelloFriendsWellHelloFriendsWellHelloFriends", 64);
  1078. rsa.encrypt(enc, dec);
  1079. rsa.decrypt(dec, enc);
  1080. dbg() << "enc size " << enc.size() << " dec size " << dec.size();
  1081. if (memcmp(enc.data(), "WellHelloFriendsWellHelloFriendsWellHelloFriendsWellHelloFriends", 64) != 0) {
  1082. FAIL(Could not encrypt then decrypt);
  1083. } else {
  1084. PASS;
  1085. }
  1086. }
  1087. int tls_tests()
  1088. {
  1089. tls_test_client_hello();
  1090. return 0;
  1091. }
  1092. void tls_test_client_hello()
  1093. {
  1094. I_TEST((TLS | Connect and Data Transfer));
  1095. Core::EventLoop loop;
  1096. RefPtr<TLS::TLSv12> tls = TLS::TLSv12::construct(nullptr);
  1097. bool sent_request = false;
  1098. ByteBuffer contents = ByteBuffer::create_uninitialized(0);
  1099. tls->on_tls_ready_to_write = [&](TLS::TLSv12& tls) {
  1100. if (sent_request)
  1101. return;
  1102. sent_request = true;
  1103. if (!tls.write("GET / HTTP/1.1\r\nHost: github.com\r\nConnection: close\r\n\r\n"_b)) {
  1104. FAIL(write() failed);
  1105. loop.quit(0);
  1106. }
  1107. };
  1108. tls->on_tls_ready_to_read = [&](TLS::TLSv12& tls) {
  1109. auto data = tls.read();
  1110. if (!data.has_value()) {
  1111. FAIL(No data received);
  1112. loop.quit(1);
  1113. } else {
  1114. // print_buffer(data.value(), 16);
  1115. contents.append(data.value().data(), data.value().size());
  1116. }
  1117. };
  1118. tls->on_tls_finished = [&] {
  1119. PASS;
  1120. auto file = Core::File::open("foo.response", Core::IODevice::WriteOnly);
  1121. if (file.is_error()) {
  1122. printf("Can't write there, %s\n", file.error().characters());
  1123. loop.quit(2);
  1124. return;
  1125. }
  1126. file.value()->write(contents);
  1127. file.value()->close();
  1128. loop.quit(0);
  1129. };
  1130. tls->on_tls_error = [&](TLS::AlertDescription) {
  1131. FAIL(Connection failure);
  1132. loop.quit(1);
  1133. };
  1134. if (!tls->connect("github.com", 443)) {
  1135. FAIL(connect() failed);
  1136. return;
  1137. }
  1138. loop.exec();
  1139. }
  1140. int bigint_tests()
  1141. {
  1142. bigint_test_fibo500();
  1143. bigint_addition_edgecases();
  1144. bigint_subtraction();
  1145. bigint_multiplication();
  1146. bigint_division();
  1147. bigint_base10();
  1148. bigint_import_export();
  1149. return 0;
  1150. }
  1151. Crypto::UnsignedBigInteger bigint_fibonacci(size_t n)
  1152. {
  1153. Crypto::UnsignedBigInteger num1(0);
  1154. Crypto::UnsignedBigInteger num2(1);
  1155. for (size_t i = 0; i < n; ++i) {
  1156. Crypto::UnsignedBigInteger t = num1.plus(num2);
  1157. num2 = num1;
  1158. num1 = t;
  1159. }
  1160. return num1;
  1161. }
  1162. void bigint_test_fibo500()
  1163. {
  1164. {
  1165. I_TEST((BigInteger | Fibonacci500));
  1166. bool pass = (bigint_fibonacci(500).words() == AK::Vector<u32> { 315178285, 505575602, 1883328078, 125027121, 3649625763, 347570207, 74535262, 3832543808, 2472133297, 1600064941, 65273441 });
  1167. if (pass) {
  1168. PASS;
  1169. } else {
  1170. FAIL(Incorrect Result);
  1171. }
  1172. }
  1173. }
  1174. void bigint_addition_edgecases()
  1175. {
  1176. {
  1177. I_TEST((BigInteger | Edge Cases));
  1178. Crypto::UnsignedBigInteger num1;
  1179. Crypto::UnsignedBigInteger num2(70);
  1180. Crypto::UnsignedBigInteger num3 = num1.plus(num2);
  1181. bool pass = (num3 == num2);
  1182. pass &= (num1 == Crypto::UnsignedBigInteger(0));
  1183. if (pass) {
  1184. PASS;
  1185. } else {
  1186. FAIL(Incorrect Result);
  1187. }
  1188. }
  1189. {
  1190. I_TEST((BigInteger | Borrow with zero));
  1191. Crypto::UnsignedBigInteger num1({ UINT32_MAX - 3, UINT32_MAX });
  1192. Crypto::UnsignedBigInteger num2({ UINT32_MAX - 2, 0 });
  1193. if (num1.plus(num2).words() == Vector<u32> { 4294967289, 0, 1 }) {
  1194. PASS;
  1195. } else {
  1196. FAIL(Incorrect Result);
  1197. }
  1198. }
  1199. }
  1200. void bigint_subtraction()
  1201. {
  1202. {
  1203. I_TEST((BigInteger | Simple Subtraction 1));
  1204. Crypto::UnsignedBigInteger num1(80);
  1205. Crypto::UnsignedBigInteger num2(70);
  1206. if (num1.minus(num2) == Crypto::UnsignedBigInteger(10)) {
  1207. PASS;
  1208. } else {
  1209. FAIL(Incorrect Result);
  1210. }
  1211. }
  1212. {
  1213. I_TEST((BigInteger | Simple Subtraction 2));
  1214. Crypto::UnsignedBigInteger num1(50);
  1215. Crypto::UnsignedBigInteger num2(70);
  1216. if (num1.minus(num2).is_invalid()) {
  1217. PASS;
  1218. } else {
  1219. FAIL(Incorrect Result);
  1220. }
  1221. }
  1222. {
  1223. I_TEST((BigInteger | Subtraction with borrow));
  1224. Crypto::UnsignedBigInteger num1(UINT32_MAX);
  1225. Crypto::UnsignedBigInteger num2(1);
  1226. Crypto::UnsignedBigInteger num3 = num1.plus(num2);
  1227. Crypto::UnsignedBigInteger result = num3.minus(num2);
  1228. if (result == num1) {
  1229. PASS;
  1230. } else {
  1231. FAIL(Incorrect Result);
  1232. }
  1233. }
  1234. {
  1235. I_TEST((BigInteger | Subtraction with large numbers));
  1236. Crypto::UnsignedBigInteger num1 = bigint_fibonacci(343);
  1237. Crypto::UnsignedBigInteger num2 = bigint_fibonacci(218);
  1238. Crypto::UnsignedBigInteger result = num1.minus(num2);
  1239. if ((result.plus(num2) == num1)
  1240. && (result.words() == Vector<u32> { 811430588, 2958904896, 1130908877, 2830569969, 3243275482, 3047460725, 774025231, 7990 })) {
  1241. PASS;
  1242. } else {
  1243. FAIL(Incorrect Result);
  1244. }
  1245. }
  1246. {
  1247. I_TEST((BigInteger | Subtraction with large numbers 2));
  1248. Crypto::UnsignedBigInteger num1(Vector<u32> { 1483061863, 446680044, 1123294122, 191895498, 3347106536, 16, 0, 0, 0 });
  1249. Crypto::UnsignedBigInteger num2(Vector<u32> { 4196414175, 1117247942, 1123294122, 191895498, 3347106536, 16 });
  1250. Crypto::UnsignedBigInteger result = num1.minus(num2);
  1251. // this test only verifies that we don't crash on an assertion
  1252. PASS;
  1253. }
  1254. {
  1255. I_TEST((BigInteger | Subtraction Regression 1));
  1256. auto num = Crypto::UnsignedBigInteger { 1 }.shift_left(256);
  1257. if (num.minus(1).words() == Vector<u32> { 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 4294967295, 0 }) {
  1258. PASS;
  1259. } else {
  1260. FAIL(Incorrect Result);
  1261. }
  1262. }
  1263. }
  1264. void bigint_multiplication()
  1265. {
  1266. {
  1267. I_TEST((BigInteger | Simple Multiplication));
  1268. Crypto::UnsignedBigInteger num1(8);
  1269. Crypto::UnsignedBigInteger num2(251);
  1270. Crypto::UnsignedBigInteger result = num1.multiplied_by(num2);
  1271. if (result.words() == Vector<u32> { 2008 }) {
  1272. PASS;
  1273. } else {
  1274. FAIL(Incorrect Result);
  1275. }
  1276. }
  1277. {
  1278. I_TEST((BigInteger | Multiplications with big numbers 1));
  1279. Crypto::UnsignedBigInteger num1 = bigint_fibonacci(200);
  1280. Crypto::UnsignedBigInteger num2(12345678);
  1281. Crypto::UnsignedBigInteger result = num1.multiplied_by(num2);
  1282. if (result.words() == Vector<u32> { 669961318, 143970113, 4028714974, 3164551305, 1589380278, 2 }) {
  1283. PASS;
  1284. } else {
  1285. FAIL(Incorrect Result);
  1286. }
  1287. }
  1288. {
  1289. I_TEST((BigInteger | Multiplications with big numbers 2));
  1290. Crypto::UnsignedBigInteger num1 = bigint_fibonacci(200);
  1291. Crypto::UnsignedBigInteger num2 = bigint_fibonacci(341);
  1292. Crypto::UnsignedBigInteger result = num1.multiplied_by(num2);
  1293. if (result.words() == Vector<u32> { 3017415433, 2741793511, 1957755698, 3731653885, 3154681877, 785762127, 3200178098, 4260616581, 529754471, 3632684436, 1073347813, 2516430 }) {
  1294. PASS;
  1295. } else {
  1296. FAIL(Incorrect Result);
  1297. }
  1298. }
  1299. }
  1300. void bigint_division()
  1301. {
  1302. {
  1303. I_TEST((BigInteger | Simple Division));
  1304. Crypto::UnsignedBigInteger num1(27194);
  1305. Crypto::UnsignedBigInteger num2(251);
  1306. auto result = num1.divided_by(num2);
  1307. Crypto::UnsignedDivisionResult expected = { Crypto::UnsignedBigInteger(108), Crypto::UnsignedBigInteger(86) };
  1308. if (result.quotient == expected.quotient && result.remainder == expected.remainder) {
  1309. PASS;
  1310. } else {
  1311. FAIL(Incorrect Result);
  1312. }
  1313. }
  1314. {
  1315. I_TEST((BigInteger | Division with big numbers));
  1316. Crypto::UnsignedBigInteger num1 = bigint_fibonacci(386);
  1317. Crypto::UnsignedBigInteger num2 = bigint_fibonacci(238);
  1318. auto result = num1.divided_by(num2);
  1319. Crypto::UnsignedDivisionResult expected = {
  1320. Crypto::UnsignedBigInteger(Vector<u32> { 2300984486, 2637503534, 2022805584, 107 }),
  1321. Crypto::UnsignedBigInteger(Vector<u32> { 1483061863, 446680044, 1123294122, 191895498, 3347106536, 16, 0, 0, 0 })
  1322. };
  1323. if (result.quotient == expected.quotient && result.remainder == expected.remainder) {
  1324. PASS;
  1325. } else {
  1326. FAIL(Incorrect Result);
  1327. }
  1328. }
  1329. {
  1330. I_TEST((BigInteger | Combined test));
  1331. auto num1 = bigint_fibonacci(497);
  1332. auto num2 = bigint_fibonacci(238);
  1333. auto div_result = num1.divided_by(num2);
  1334. if (div_result.quotient.multiplied_by(num2).plus(div_result.remainder) == num1) {
  1335. PASS;
  1336. } else {
  1337. FAIL(Incorrect Result);
  1338. }
  1339. }
  1340. }
  1341. void bigint_base10()
  1342. {
  1343. {
  1344. I_TEST((BigInteger | From String));
  1345. auto result = Crypto::UnsignedBigInteger::from_base10("57195071295721390579057195715793");
  1346. if (result.words() == Vector<u32> { 3806301393, 954919431, 3879607298, 721 }) {
  1347. PASS;
  1348. } else {
  1349. FAIL(Incorrect Result);
  1350. }
  1351. }
  1352. {
  1353. I_TEST((BigInteger | To String));
  1354. auto result = Crypto::UnsignedBigInteger { Vector<u32> { 3806301393, 954919431, 3879607298, 721 } }.to_base10();
  1355. if (result == "57195071295721390579057195715793") {
  1356. PASS;
  1357. } else {
  1358. FAIL(Incorrect Result);
  1359. }
  1360. }
  1361. }
  1362. void bigint_import_export()
  1363. {
  1364. {
  1365. I_TEST((BigInteger | BigEndian Decode / Encode roundtrip));
  1366. u8 random_bytes[128];
  1367. u8 target_buffer[128];
  1368. arc4random_buf(random_bytes, 128);
  1369. auto encoded = Crypto::UnsignedBigInteger::import_data(random_bytes, 128);
  1370. encoded.export_data(target_buffer, 128);
  1371. if (memcmp(target_buffer, random_bytes, 128) != 0)
  1372. FAIL(Could not roundtrip);
  1373. else
  1374. PASS;
  1375. }
  1376. {
  1377. I_TEST((BigInteger | BigEndian Encode / Decode roundtrip));
  1378. u8 target_buffer[128];
  1379. auto encoded = "12345678901234567890"_bigint;
  1380. auto size = encoded.export_data(target_buffer, 128);
  1381. auto decoded = Crypto::UnsignedBigInteger::import_data(target_buffer, size);
  1382. if (encoded != decoded)
  1383. FAIL(Could not roundtrip);
  1384. else
  1385. PASS;
  1386. }
  1387. {
  1388. I_TEST((BigInteger | BigEndian Import));
  1389. auto number = Crypto::UnsignedBigInteger::import_data("hello");
  1390. if (number == "448378203247"_bigint) {
  1391. PASS;
  1392. } else {
  1393. FAIL(Invalid value);
  1394. }
  1395. }
  1396. {
  1397. I_TEST((BigInteger | BigEndian Export));
  1398. auto number = "448378203247"_bigint;
  1399. char exported[8] { 0 };
  1400. auto exported_length = number.export_data((u8*)exported, 8);
  1401. if (exported_length == 5 && memcmp(exported + 3, "hello", 5) == 0) {
  1402. PASS;
  1403. } else {
  1404. FAIL(Invalid value);
  1405. print_buffer(ByteBuffer::wrap(exported - exported_length + 8, exported_length), -1);
  1406. }
  1407. }
  1408. }