25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

9 년 전
8 년 전
8 년 전
9 년 전
9 년 전
9 년 전
8 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
9 년 전
8 년 전
9 년 전
9 년 전
8 년 전
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. #include "src/common.h"
  2. #include "src/pkcs7.h"
  3. #include "src/enc_modes.h"
  4. #include "src/base64.h"
  5. #include <assert.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdbool.h>
  9. #include <string.h>
  10. #include <time.h>
  11. #include <openssl/evp.h>
  12. #include <openssl/rand.h>
  13. #include <assert.h>
  14. #include "set2.h"
  15. Result_t OpenSSL::Cbc(CryptoAttribs_t* i_attribs,
  16. const Key_t* const i_key)
  17. {
  18. if(NULL==i_attribs->output)
  19. {
  20. i_attribs->output = (uint8_t*) malloc(i_attribs->input_len);
  21. }
  22. int ret=0;
  23. EVP_CIPHER_CTX ctx;
  24. EVP_CIPHER_CTX_init(&ctx);
  25. OP_CHECK(
  26. EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, i_key->key, i_attribs->iv,
  27. i_attribs->operation==kEncrypt ? 1 : 0));
  28. EVP_CIPHER_CTX_set_padding(&ctx, 0);
  29. EVP_CIPHER_CTX_set_key_length(&ctx, i_key->len);
  30. OP_CHECK(
  31. EVP_CipherUpdate(&ctx, i_attribs->output, &ret, i_attribs->input,
  32. i_attribs->input_len));
  33. i_attribs->output_len = ret;
  34. OP_CHECK(
  35. EVP_CipherFinal_ex(&ctx, &i_attribs->output[ret], &ret));
  36. i_attribs->output_len += ret;
  37. EVP_CIPHER_CTX_cleanup(&ctx);
  38. return Result_OK;
  39. end:
  40. return Result_Error;
  41. }
  42. TCASE(ecb_encrypt_decrypt_single_block)
  43. {
  44. static const uint8_t expected_result[17] = "0123456789123456";
  45. CryptoAttribs_t encode, decode;
  46. Key_t key1;
  47. CryptoAttribs_t::Init(&encode);
  48. CryptoAttribs_t::Init(&decode);
  49. Key_t::Init(&key1);
  50. uint8_t input[16];
  51. uint8_t output[16];
  52. uint8_t key[16];
  53. encode.input = input;
  54. encode.input_len= sizeof(input);
  55. decode.input = output;
  56. decode.input_len= sizeof(output);
  57. key1.key = key;
  58. key1.len = sizeof(key);
  59. memcpy(key1.key, "YELLOW SUBMARINE", 16);
  60. memcpy(encode.input, expected_result, 16);
  61. CHECK(ecb_encrypt(&encode, &key1) == Result_OK);
  62. CHECK(encode.output_len==16);
  63. memcpy(decode.input, encode.output, 16);
  64. ecb_decrypt(&decode, &key1);
  65. CHECK(decode.output_len == 16);
  66. CHECK(memcmp(decode.output, expected_result, 16) == 0);
  67. free(encode.output);
  68. free(decode.output);
  69. }
  70. TCASE_E
  71. TCASE(set2_challange9)
  72. {
  73. const uint8_t text1[] = "Text1";
  74. uint8_t unpadded[32] = {0};
  75. uint8_t* p_unpadded = &unpadded[0];
  76. int ret;
  77. uint8_t buff1[32];
  78. uint8_t* p_buff1 = &buff1[0];
  79. char buff2[10];
  80. ret = pkcs7_pad(text1, 5, &p_buff1, 32);
  81. CHECK(ret==true, (const unsigned char* const) "Padding operation failed");
  82. ret = memcmp(text1, buff1, 5);
  83. CHECK(ret==0, (const unsigned char* const) "Content differs");
  84. for(int i=5; i<32; i++)
  85. {
  86. CHECK(buff1[i] == 27, (const unsigned char* const) "Wrong padding");
  87. }
  88. size_t unpad_len = 0;
  89. CHECK( pkcs7_unpad(&buff1[0], 32, &p_unpadded, &unpad_len) );
  90. CHECK(unpad_len == 5, (const uint8_t*) "Unpadded length wrong");
  91. CHECK( 0==memcmp(text1, unpadded, unpad_len) );
  92. }
  93. TCASE_E
  94. TCASE(set2_challange10)
  95. {
  96. static const uint8_t expected_result[34] = "I'm back and I'm ringin' the bell";
  97. CryptoAttribs_t attribs;
  98. Key_t key;
  99. Result_t res = Result_Error;
  100. Key_t::Init(&key);
  101. key.len = 16;
  102. key.key = (uint8_t*) malloc(key.len);
  103. memcpy(key.key,"YELLOW SUBMARINE",key.len);
  104. CryptoAttribs_t::Init(&attribs);
  105. attribs.iv = (uint8_t*) malloc(key.len);
  106. attribs.iv_len = key.len;
  107. memset(attribs.iv, 0, attribs.iv_len);
  108. res = load_base64_to_hex(
  109. "sol/etc/set2_t2.txt",
  110. &(attribs.input),
  111. &(attribs.input_len));
  112. CHECK(res == Result_OK, (const uint8_t*) "Problem when loading input file");
  113. cbc_decrypt(&attribs, &key);
  114. CHECK( memcmp(expected_result, attribs.output, 33) == 0, (const uint8_t*)
  115. "Wrong plaintext decrypted");
  116. // cleanup
  117. CryptoAttribs_t::Free(&attribs);
  118. Key_t::Free(&key);
  119. }
  120. TCASE_E
  121. TCASE(cbc_enc_dec_test)
  122. {
  123. static const uint8_t test_text[49] = "The quick brown fox jumps over the lazy mad dog.";
  124. CryptoAttribs_t enc_attribs;
  125. CryptoAttribs_t dec_attribs;
  126. Key_t key;
  127. CryptoAttribs_t::Init(&enc_attribs);
  128. CryptoAttribs_t::Init(&dec_attribs);
  129. Key_t::Init(&key);
  130. // Setup key
  131. key.len = 16;
  132. key.key = (uint8_t*) malloc(key.len);
  133. memcpy(key.key, "0123456789123456", key.len);
  134. // Encrypt
  135. enc_attribs.input_len = sizeof(test_text)-1;
  136. enc_attribs.input = (uint8_t*) malloc(enc_attribs.input_len);
  137. enc_attribs.operation = kEncrypt;
  138. memcpy( enc_attribs.input, test_text, enc_attribs.input_len);
  139. enc_attribs.iv_len = key.len;
  140. enc_attribs.iv = (uint8_t*)malloc(enc_attribs.iv_len);
  141. memset(enc_attribs.iv, 0, enc_attribs.iv_len);
  142. cbc_encrypt(&enc_attribs, &key);
  143. // Setup decryption object.
  144. dec_attribs.iv = (uint8_t*)malloc( enc_attribs.iv_len );
  145. dec_attribs.iv_len = enc_attribs.iv_len;
  146. dec_attribs.operation = kDecrypt;
  147. memset(dec_attribs.iv, 0, dec_attribs.iv_len);
  148. dec_attribs.input = (uint8_t*)malloc(enc_attribs.output_len);
  149. dec_attribs.input_len = enc_attribs.output_len;
  150. memcpy(dec_attribs.input, enc_attribs.output, enc_attribs.output_len);
  151. // Decrypt
  152. cbc_decrypt(&dec_attribs, &key);
  153. CHECK( dec_attribs.output_len+1 == sizeof(test_text), (uint8_t*) "wrong size of ouptut");
  154. CHECK(memcmp(dec_attribs.output, test_text, dec_attribs.output_len) == 0, dec_attribs.output);
  155. end:
  156. CryptoAttribs_t::Free(&enc_attribs);
  157. CryptoAttribs_t::Free(&dec_attribs);
  158. Key_t::Free(&key);
  159. }
  160. TCASE_E
  161. TCASE(encode_decode_openssl)
  162. {
  163. uint8_t concatenated_blocks[16*3];
  164. uint8_t iv1[16] = {0};
  165. uint8_t key[17] = "YELLOW SUBMARINE"; // 16+'\0' = 17
  166. memset(concatenated_blocks, 2, 16);
  167. memset(&concatenated_blocks[16], 5, 16);
  168. memset(&concatenated_blocks[32], 9, 16);
  169. RAND_bytes(iv1, 16);
  170. Key_t keyObj;
  171. keyObj.key = &key[0];
  172. keyObj.len = 16;
  173. // 1. decryption test
  174. {
  175. CryptoAttribs_t attribs_openssl_enc;
  176. CryptoAttribs_t::Init(&attribs_openssl_enc);
  177. attribs_openssl_enc.input = concatenated_blocks;
  178. attribs_openssl_enc.input_len = sizeof(concatenated_blocks);
  179. attribs_openssl_enc.output = (uint8_t*)malloc(attribs_openssl_enc.input_len);
  180. attribs_openssl_enc.output_len;
  181. attribs_openssl_enc.iv = &iv1[0];
  182. attribs_openssl_enc.iv_len = sizeof(iv1);
  183. attribs_openssl_enc.operation = kEncrypt;
  184. CHECK(OpenSSL::Cbc(&attribs_openssl_enc, &keyObj)==Result_OK);
  185. CHECK(attribs_openssl_enc.output_len==48, (uint8_t*)"Ciphertext has wrong size");//
  186. CryptoAttribs_t cbc_attribs;
  187. CryptoAttribs_t::Init(&cbc_attribs);
  188. cbc_attribs.input = attribs_openssl_enc.output;
  189. cbc_attribs.input_len = attribs_openssl_enc.output_len;
  190. cbc_attribs.iv = &iv1[0];
  191. cbc_attribs.iv_len = sizeof(iv1);
  192. CHECK( Result_OK == cbc_decrypt(&cbc_attribs, &keyObj) );
  193. CHECK(
  194. memcmp( concatenated_blocks,
  195. cbc_attribs.output,
  196. cbc_attribs.output_len) == 0,
  197. (uint8_t*)"Input/Output differs");
  198. ::free(attribs_openssl_enc.output);
  199. ::free(cbc_attribs.output);
  200. }
  201. // 2. encryption test
  202. {
  203. CryptoAttribs_t attribs_enc;
  204. CryptoAttribs_t::Init(&attribs_enc);
  205. attribs_enc.input = concatenated_blocks;
  206. attribs_enc.input_len = sizeof(concatenated_blocks);
  207. attribs_enc.iv = &iv1[0];
  208. attribs_enc.iv_len = sizeof(iv1);
  209. attribs_enc.operation = kEncrypt;
  210. CHECK( Result_OK == cbc_encrypt(&attribs_enc, &keyObj) );
  211. CHECK( 48 == attribs_enc.output_len );
  212. CHECK( NULL != attribs_enc.output );
  213. CryptoAttribs_t attribs_openssl_dec;
  214. CryptoAttribs_t::Init(&attribs_openssl_dec);
  215. attribs_openssl_dec.input = attribs_enc.output;
  216. attribs_openssl_dec.input_len = attribs_enc.output_len;
  217. attribs_openssl_dec.iv = &iv1[0];
  218. attribs_openssl_dec.iv_len = sizeof(iv1);
  219. attribs_openssl_dec.operation = kDecrypt;
  220. CHECK(OpenSSL::Cbc(&attribs_openssl_dec, &keyObj)==Result_OK);
  221. CHECK(attribs_openssl_dec.output_len==48, (uint8_t*)"Ciphertext has wrong size");
  222. CHECK(
  223. memcmp( concatenated_blocks,
  224. attribs_openssl_dec.output,
  225. attribs_openssl_dec.output_len) == 0,
  226. (uint8_t*)"Input/Output differs");
  227. ::free(attribs_enc.output);
  228. ::free(attribs_openssl_dec.output);
  229. }
  230. }
  231. TCASE_E
  232. /* -------------------------------------------------------------------------
  233. Checks if ciphertext is encrypted with ECB or CBC.
  234. Requirement: In order to work, plaintext must encrypt up to 6 blocks (with
  235. padding) and all the letters in the PT must be exactly the same.
  236. Returns:
  237. * 0 : if ciphertext encrypted with ECB
  238. * 1 : if ciphertext encrypted with CBC
  239. * 0xFF: in case wrong input parameters provided
  240. -------------------------------------------------------------------------*/
  241. uint8_t check_ciphertext(const uint8_t* ciphertext, uint32_t len )
  242. {
  243. uint32_t bs = 16;
  244. if( (len < 6*bs) || (len>7*bs) )
  245. return 0xFF;
  246. // check blocks 2,3,4 as first have prepaned bytes, 5th also, 6th can have padding
  247. // eventually 7th may be fully padded.
  248. for(uint32_t i=1; i<4; ++i)
  249. {
  250. if( memcmp(ciphertext+(bs*i), ciphertext+(bs*(i+1)), bs) != 0)
  251. return 1; // Two blocks differ -> must be CBC
  252. }
  253. return 0; // All checked blocks are the same -> ECB
  254. }
  255. Result_t encryption_oracle( const uint8_t* pt,
  256. uint32_t pt_len,
  257. uint8_t* ct,
  258. uint32_t* ct_len,
  259. uint8_t* mode)
  260. {
  261. uint8_t iv1[16] = {0};
  262. uint8_t key[16] = {0};
  263. uint8_t prepend_byte_size;
  264. uint8_t append_byte_size;
  265. uint8_t random_bytes[10];
  266. uint8_t encryption_mode = 0xFF;
  267. struct timespec tv;
  268. CryptoAttribs_t attribs;
  269. Key_t keyObj;
  270. // get seed for good randomnes
  271. clock_gettime(CLOCK_MONOTONIC, &tv);
  272. srand((unsigned int)tv.tv_nsec);
  273. // choose random sizes and enc mode (0 ECB, 1 CBC)
  274. prepend_byte_size = 5+(rand() % 6);
  275. append_byte_size = 5+(rand() % 6);
  276. encryption_mode = rand() % 2;
  277. // generate rando data
  278. RAND_bytes(iv1, 16);
  279. RAND_bytes(key, 16);
  280. // initialize encryption attribs
  281. CryptoAttribs_t::Init(&attribs);
  282. attribs.operation = kEncrypt;
  283. attribs.input_len = 0;
  284. attribs.input = (uint8_t*)malloc(7*16);
  285. attribs.output_len = 0;
  286. attribs.output = (uint8_t*)malloc(7*16);
  287. attribs.padding = kPadding_PKCS7;
  288. // copy input to the input buffer
  289. RAND_bytes(random_bytes, prepend_byte_size);
  290. int tmplen=0;
  291. memcpy(attribs.input+tmplen, random_bytes, prepend_byte_size);
  292. tmplen+=prepend_byte_size;
  293. memcpy(attribs.input+tmplen, pt, pt_len);
  294. tmplen+=pt_len;
  295. RAND_bytes(random_bytes, append_byte_size);
  296. memcpy(attribs.input+tmplen, random_bytes, append_byte_size);
  297. tmplen+=append_byte_size;
  298. attribs.input_len = tmplen;
  299. // key
  300. Key_t::Init(&keyObj);
  301. keyObj.key = key;
  302. keyObj.len = 16;
  303. Result_t ret = Result_OK;
  304. do
  305. {
  306. if(encryption_mode)
  307. {
  308. attribs.iv = (uint8_t*)malloc(16);
  309. attribs.iv_len = 16;
  310. RAND_bytes(attribs.iv, 16);
  311. if( Result_OK!=cbc_encrypt(&attribs, &keyObj) )
  312. {
  313. ret = Result_Error;
  314. break;
  315. }
  316. }
  317. else
  318. {
  319. if( Result_OK!=ecb_encrypt(&attribs, &keyObj) )
  320. {
  321. ret = Result_Error;
  322. break;
  323. }
  324. }
  325. // Copy results
  326. memcpy(ct, attribs.output, attribs.output_len);
  327. *ct_len = attribs.output_len;
  328. *mode = encryption_mode;
  329. ret = Result_OK;
  330. } while(false);
  331. CryptoAttribs_t::Free(&attribs);
  332. return ret;
  333. }
  334. TCASE(set2_challange11)
  335. {
  336. // let's run it 1000 times
  337. for(size_t i=0; i<1000; ++i)
  338. {
  339. uint8_t plaintext[5*16] = {0};
  340. uint8_t ciphertext[7*16] = {0};
  341. uint8_t mode = 0xFF;
  342. uint8_t guessed_mode = 0xFF;
  343. uint32_t ciphertext_len = 7*16;
  344. // set data in blocks so that 5 blocks is 11111...
  345. memset(plaintext, 1, 5*16);
  346. Result_t ret = encryption_oracle(plaintext, 5*16, ciphertext, &ciphertext_len, &mode);
  347. CHECK(ret == Result_OK, (uint8_t*)"Error occured on encryption");
  348. CHECK(mode != 0xFF);
  349. guessed_mode = check_ciphertext(ciphertext, ciphertext_len);
  350. CHECK(mode == guessed_mode);
  351. }
  352. }
  353. TCASE_E
  354. TCASE(encrypt_padding_pkcs7)
  355. {
  356. uint8_t text[3] = {'D', 'E', 'F'};
  357. uint8_t expected_no_padding_dec[16] = {0};
  358. uint8_t iv[16] = {0};
  359. uint8_t key[16] = {0};
  360. // "ABC" must be padded with 13,13,13....
  361. memcpy(expected_no_padding_dec, text, 3);
  362. memset(expected_no_padding_dec+3, 13, 13);
  363. // key
  364. Key_t keyObj = {0};
  365. Key_t::Init(&keyObj);
  366. keyObj.key = key;
  367. keyObj.len = 16;
  368. CryptoAttribs_t attribs_enc;
  369. CryptoAttribs_t::Init(&attribs_enc);
  370. attribs_enc.input = &text[0];
  371. attribs_enc.input_len = 3;
  372. attribs_enc.iv = &iv[0];
  373. attribs_enc.iv_len = sizeof(iv);
  374. attribs_enc.operation = kEncrypt;
  375. attribs_enc.padding = kPadding_PKCS7;
  376. CHECK( Result_OK == cbc_encrypt(&attribs_enc, &keyObj) );
  377. CHECK( attribs_enc.output_len == 16, (uint8_t*) "Wrong out size");
  378. // Decrypt with openssl and no padding. Check padding value
  379. {
  380. CryptoAttribs_t attribs_openssl_dec;
  381. CryptoAttribs_t::Init(&attribs_openssl_dec);
  382. attribs_openssl_dec.input = attribs_enc.output;
  383. attribs_openssl_dec.input_len = attribs_enc.output_len;
  384. attribs_openssl_dec.iv = &iv[0];
  385. attribs_openssl_dec.iv_len = sizeof(iv);
  386. attribs_openssl_dec.operation = kDecrypt;
  387. attribs_openssl_dec.padding = kPadding_None;
  388. CHECK(OpenSSL::Cbc(&attribs_openssl_dec, &keyObj)==Result_OK);
  389. CHECK(attribs_openssl_dec.output_len==16, (uint8_t*)"Ciphertext has wrong size");
  390. CHECK( 0==memcmp( attribs_openssl_dec.output,
  391. expected_no_padding_dec,
  392. 16), (uint8_t*)"Wrong padding decrypted" );
  393. ::free(attribs_openssl_dec.output);
  394. }
  395. // Decrypt padding
  396. {
  397. CryptoAttribs_t attribs_dec;
  398. CryptoAttribs_t::Init(&attribs_dec);
  399. attribs_dec.input = attribs_enc.output;
  400. attribs_dec.input_len = attribs_enc.output_len;
  401. attribs_dec.iv = &iv[0];
  402. attribs_dec.iv_len = sizeof(iv);
  403. attribs_dec.operation = kDecrypt;
  404. attribs_dec.padding = kPadding_PKCS7;
  405. CHECK( Result_OK == cbc_decrypt(&attribs_dec, &keyObj) );
  406. CHECK(attribs_dec.output_len==3, (uint8_t*)"Ciphertext has wrong size");
  407. CHECK( 0==memcmp( attribs_dec.output,
  408. expected_no_padding_dec,
  409. 3), (uint8_t*)"Wrong padding decrypted" );
  410. ::free(attribs_dec.output);
  411. }
  412. ::free(attribs_enc.output);
  413. }
  414. TCASE_E
  415. TCASE(set2_challange12_not_finished)
  416. {
  417. uint8_t CIPHERTEXT[] = "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg"
  418. "aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq"
  419. "dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg"
  420. "YnkK";
  421. uint8_t HEX_STRING[sizeof CIPHERTEXT];
  422. uint8_t CONCAT_STRING[sizeof(CIPHERTEXT)*2];
  423. CryptoAttribs_t EncryptForBS;
  424. Key_t key;
  425. uint32_t hex_len = 0;
  426. hex_len = base64_to_hex(CIPHERTEXT, sizeof(CIPHERTEXT), HEX_STRING);
  427. }
  428. TCASE_E