test-crypto.cpp 47 KB

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