aesgcm.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
  2. /* SPDX-License-Identifier: Unlicense */
  3. /**
  4. @file aesgcm.c
  5. AES128-GCM demo - file en-&decryption, Steffen Jaeckel
  6. Uses the format: |ciphertext|tag-16-bytes|
  7. */
  8. #define _GNU_SOURCE
  9. #include <tomcrypt.h>
  10. #include <stdio.h>
  11. #include <stdint.h>
  12. #include <sys/stat.h>
  13. #include <sys/types.h>
  14. #include <dirent.h>
  15. #include <string.h>
  16. #include <fcntl.h>
  17. #include <unistd.h>
  18. #ifndef LTC_GCM_MODE
  19. int main(void)
  20. {
  21. return -1;
  22. }
  23. #else
  24. #include "gcm-file/gcm_filehandle.c"
  25. #include "gcm-file/gcm_file.c"
  26. static off_t fsize(const char *filename)
  27. {
  28. struct stat st;
  29. if (stat(filename, &st) == 0) return st.st_size;
  30. return -1;
  31. }
  32. #if defined(__linux__) && defined(__GLIBC_PREREQ)
  33. #if __GLIBC_PREREQ(2, 14)
  34. #define HAS_SYNCFS
  35. #endif
  36. #endif
  37. static int mv(const char *old_name, const char *new_name)
  38. {
  39. int fd;
  40. if (rename(old_name, new_name) == -1) return -1;
  41. fd = open(new_name, 0);
  42. if (fd == -1) return -1;
  43. #if !defined(_WIN32)
  44. if (fsync(fd) != 0) goto OUT;
  45. #if defined(HAS_SYNCFS)
  46. syncfs(fd);
  47. #else
  48. sync();
  49. #endif
  50. OUT:
  51. #endif
  52. close(fd);
  53. return 0;
  54. }
  55. static void LTC_NORETURN die(int ret)
  56. {
  57. fprintf(stderr, "Usage: aesgcm <-e|-d> <infile> <outfile> <88|96 char hex-string 'IV | key'>\n");
  58. exit(ret);
  59. }
  60. int main(int argc, char **argv)
  61. {
  62. int ret = 0, err, arg, direction, res, tmp;
  63. size_t keylen;
  64. uint8_t keybuf[48] = {0};
  65. char *out = NULL;
  66. const char *mode, *in_file, *out_file, *key_string;
  67. unsigned long ivlen, key_len;
  68. if (argc < 5) {
  69. if (argc > 1 && strstr(argv[1], "-h"))
  70. die(0);
  71. else
  72. die(__LINE__);
  73. }
  74. arg = 1;
  75. mode = argv[arg++];
  76. in_file = argv[arg++];
  77. out_file = argv[arg++];
  78. key_string = argv[arg++];
  79. if(strcmp(mode, "-d") == 0) direction = GCM_DECRYPT;
  80. else if(strcmp(mode, "-e") == 0) direction = GCM_ENCRYPT;
  81. else die(__LINE__);
  82. if (fsize(in_file) <= 0) die(__LINE__);
  83. keylen = XSTRLEN(key_string);
  84. if (keylen != 88 && keylen != 96) die(__LINE__);
  85. key_len = sizeof(keybuf);
  86. if ((err = base16_decode(key_string, keylen, keybuf, &key_len)) != CRYPT_OK) {
  87. fprintf(stderr, "boooh %s\n", error_to_string(err));
  88. die(__LINE__);
  89. }
  90. register_all_ciphers();
  91. if(asprintf(&out, "%s-XXXXXX", out_file) < 0) die(__LINE__);
  92. if((tmp = mkstemp(out)) == -1) {
  93. ret = __LINE__;
  94. goto cleanup;
  95. }
  96. close(tmp);
  97. ivlen = keylen/2 - 32;
  98. if((err = gcm_file(find_cipher("aes"), &keybuf[ivlen], 32, keybuf, ivlen, NULL, 0, in_file, out, 16, direction, &res)) != CRYPT_OK) {
  99. fprintf(stderr, "boooh %s\n", error_to_string(err));
  100. ret = __LINE__;
  101. goto cleanup;
  102. }
  103. if(res != 1) {
  104. ret = __LINE__;
  105. }
  106. else
  107. {
  108. if (mv(out, out_file) != 0) ret = __LINE__;
  109. }
  110. cleanup:
  111. if(ret != 0) unlink(out);
  112. free(out);
  113. return ret;
  114. }
  115. #endif