Advertisement
Guest User

Untitled

a guest
Nov 20th, 2019
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.18 KB | None | 0 0
  1. #include <getopt.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4.  
  5. #include "ciphers.h"
  6.  
  7. #define MAX_FILE_BUFFER_SIZE (1024 * 1024 * 500) // 500MiB file
  8.  
  9. int read_from_file(char* filepath, unsigned char* buff, unsigned int buff_len) {
  10. FILE* fp = NULL;
  11. if ((fp = fopen(filepath, "rb")) == NULL) return 0;
  12. fseek(fp, 0L, SEEK_END);
  13. int sz = ftell(fp);
  14. fseek(fp, 0L, SEEK_SET);
  15. fread(buff, sz, 1, fp);
  16. fclose(fp);
  17. return sz;
  18. }
  19.  
  20. int write_to_file(char* filepath, unsigned char* buff, unsigned int buff_len) {
  21. FILE* fp = NULL;
  22. if ((fp = fopen(filepath, "wb")) == NULL) return 0;
  23. int ret = fwrite(buff, buff_len, 1, fp);
  24. fclose(fp);
  25. return ret;
  26. }
  27.  
  28. void usage(char* prog_name) {
  29. printf("Usage: %s [-d | --dec] --cipher=cipher --in=inputfile --out=outputfile --passfile=password_file [--aadfile=aad_file] [--format=format] [--helpq]\n", prog_name);
  30. }
  31.  
  32. int main (int argc, char** argv) {
  33. int c;
  34. char enc = 1;
  35. char* inputFilePath;
  36. char* outputFilePath;
  37. char* passFilePath;
  38. char* aadFilePath;
  39. unsigned char* aad = NULL;
  40. unsigned int aad_len;
  41. unsigned char* plaintext = NULL;
  42. int plaintext_len;
  43. unsigned char* ciphertext = NULL;
  44. int ciphertext_len;
  45. unsigned char password[512];
  46. int password_len;
  47. unsigned char tag[TAG_LEN] = {0};
  48. const EVP_CIPHER* cipher = NULL;
  49. int AEAD = 0;
  50. timer duration;
  51. unsigned long int (*get_duration)(timer* t) = &get_milliseconds;
  52. char* format = "ms";
  53. int ret = EXIT_SUCCESS;
  54.  
  55. while (1) {
  56. int option_index = 0;
  57. static struct option long_options[] = {
  58. {"cipher", required_argument, 0, 'c' },
  59. {"in", required_argument, 0, 'i' },
  60. {"out", required_argument, 0, 'o' },
  61. {"dec", no_argument, 0, 'd' },
  62. {"aadfile", required_argument, 0, 'a' },
  63. {"passfile", required_argument, 0, 'p' },
  64. {"format", required_argument, 0, 'f' },
  65. {"help", no_argument, 0, 'h' },
  66. {0, 0, 0, 0 }
  67. };
  68.  
  69. // enc/dec, infile, outfile, passfile, format, help
  70. if ((c = getopt_long(argc, argv, "dc:i:o:p:a:f:h", long_options, &option_index)) == -1)
  71. break;
  72.  
  73. switch (c) {
  74. case 'h':
  75. usage(argv[0]);
  76. return ret;
  77. case 'c':
  78. if ((cipher = EVP_get_cipherbyname(optarg)) == NULL) {
  79. printf("cipher selected %s is not supported\n", optarg);
  80. return -1;
  81. }
  82. int opt_len = strlen(optarg);
  83. if (!memcmp(optarg + opt_len - 3, "gcm", 3))
  84. AEAD = 1;
  85. break;
  86. case 'i':
  87. inputFilePath = optarg;
  88. break;
  89. case 'o':
  90. outputFilePath = optarg;
  91. break;
  92. case 'd':
  93. enc = 0;
  94. break;
  95. case 'p':
  96. passFilePath = optarg;
  97. break;
  98. case 'a':
  99. aadFilePath = optarg;
  100. break;
  101. case 'f':
  102. if (!memcmp(optarg, "milli", 5)) {
  103. format = "ms";
  104. get_duration = &get_milliseconds;
  105. } else if (!memcmp(optarg, "micro", 5)) {
  106. format = "micros";
  107. get_duration = &get_microseconds;
  108. } else if (!memcmp(optarg, "nano", 4)) {
  109. format = "ns";
  110. get_duration = &get_nanoseconds;
  111. }
  112. break;
  113. case '?':
  114. usage(argv[0]);
  115. return EXIT_FAILURE;
  116. default:
  117. break;
  118. }
  119. }
  120.  
  121. if ((plaintext = malloc(MAX_FILE_BUFFER_SIZE * sizeof(unsigned char))) == NULL) {
  122. ret = EXIT_FAILURE;
  123. goto plaintext_alloc;
  124. }
  125.  
  126. if ((ciphertext = malloc(MAX_FILE_BUFFER_SIZE * sizeof(unsigned char))) == NULL) {
  127. ret = EXIT_FAILURE;
  128. goto ciphertext_alloc;
  129. }
  130.  
  131. if (AEAD) {
  132. if ((aad = malloc(MAX_FILE_BUFFER_SIZE * sizeof(unsigned char))) == NULL) {
  133. ret = EXIT_FAILURE;
  134. goto aad_alloc;
  135. }
  136. if (!(aad_len = read_from_file(aadFilePath, aad, MAX_FILE_BUFFER_SIZE))) {
  137. fprintf(stderr, "Unable to open aad file\n");
  138. ret = EXIT_FAILURE;
  139. goto error;
  140. }
  141. }
  142.  
  143. if (enc) {
  144. if (!(plaintext_len = read_from_file(inputFilePath, plaintext, MAX_FILE_BUFFER_SIZE))) {
  145. fprintf(stderr, "Unable to open plaintext file\n");
  146. ret = EXIT_FAILURE;
  147. goto error;
  148. }
  149.  
  150. if (!(password_len = read_from_file(passFilePath, password, 512))) {
  151. fprintf(stderr, "Unable to open password file\n");
  152. ret = EXIT_FAILURE;
  153. goto error;
  154. }
  155.  
  156. if (AEAD) {
  157. if ((ciphertext_len = gcm_encrypt(cipher, plaintext, plaintext_len,
  158. password, password_len, aad, aad_len, ciphertext, tag, &duration)) <= 0) {
  159. fprintf(stderr, "wrong encrypting\n");
  160. ret = EXIT_FAILURE;
  161. goto error;
  162. }
  163. //print_hexbuf("C", ciphertext, ciphertext_len);
  164. memcpy(ciphertext + ciphertext_len, tag, TAG_LEN); // copy tag to ciphertext end
  165. ciphertext_len += TAG_LEN;
  166. } else
  167. if ((ciphertext_len = encrypt(cipher, plaintext, plaintext_len, password, password_len, ciphertext, &duration)) <= 0) {
  168. fprintf(stderr, "wrong encrypting\n");
  169. ret = EXIT_FAILURE;
  170. goto error;
  171. }
  172.  
  173. printf("encryption took %lu %s\n", get_duration(&duration), format);
  174.  
  175. if (!write_to_file(outputFilePath, ciphertext, ciphertext_len)) {
  176. fprintf(stderr, "Unable to open output file\n");
  177. ret = EXIT_FAILURE;
  178. goto error;
  179. }
  180. } else {
  181. if (!(ciphertext_len = read_from_file(inputFilePath, ciphertext, MAX_FILE_BUFFER_SIZE))) {
  182. fprintf(stderr, "Unable to open ciphertext file\n");
  183. ret = EXIT_FAILURE;
  184. goto error;
  185. }
  186.  
  187. if (!(password_len = read_from_file(passFilePath, password, 512))) {
  188. fprintf(stderr, "Unable to open password file\n");
  189. ret = EXIT_FAILURE;
  190. goto error;
  191. }
  192.  
  193. if (AEAD) {
  194. ciphertext_len -= TAG_LEN;
  195. memcpy(tag, ciphertext + ciphertext_len, TAG_LEN); // copy ciphertext end to tag
  196. // check authenticated decryption
  197. if ((plaintext_len = gcm_decrypt(cipher, ciphertext, ciphertext_len,
  198. password, password_len, aad, aad_len, tag, plaintext, &duration)) <= 0) {
  199. fprintf(stderr, "wrong decrypting\n");
  200. ret = EXIT_FAILURE;
  201. goto error;
  202. }
  203. } else
  204. plaintext_len = decrypt(cipher, ciphertext, ciphertext_len, password, password_len, plaintext, &duration);
  205.  
  206. printf("decryption took %lu %s\n", get_duration(&duration), format);
  207.  
  208. if (!write_to_file(outputFilePath, plaintext, plaintext_len)) {
  209. fprintf(stderr, "Unable to open output file\n");
  210. ret = EXIT_FAILURE;
  211. goto error;
  212. }
  213. }
  214.  
  215. error:
  216. free(ciphertext);
  217. ciphertext_alloc:
  218. free(plaintext);
  219. plaintext_alloc:
  220. if (aad != NULL) free(aad);
  221. aad_alloc:
  222. return ret;
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement