uencrypt.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* SPDX-License-Identifier: GPL-2.0-or-later
  2. * Copyright (C) 2023 Eneas Ulir de Queiroz
  3. */
  4. #include <errno.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include "uencrypt.h"
  10. static void check_enc_dec(const int enc)
  11. {
  12. if (enc == -1)
  13. return;
  14. fprintf(stderr, "Error: both -d and -e were specified.\n");
  15. exit(EXIT_FAILURE);
  16. }
  17. static void show_usage(const char* name)
  18. {
  19. fprintf(stderr, "Usage: %s: [-d | -e] [-n] -k key [-i iv] [-c cipher]\n"
  20. "-d = decrypt; -e = encrypt; -n = no padding\n", name);
  21. }
  22. static void uencrypt_clear_free(void *ptr, size_t len)
  23. {
  24. if (ptr) {
  25. memset(ptr, 0, len);
  26. free(ptr);
  27. }
  28. }
  29. int main(int argc, char *argv[])
  30. {
  31. int enc = -1;
  32. unsigned char *iv = NULL;
  33. unsigned char *key = NULL;
  34. long keylen = 0, ivlen = 0;
  35. int opt;
  36. int padding = 1;
  37. const cipher_t *cipher = get_default_cipher();
  38. ctx_t* ctx;
  39. int ret = EXIT_FAILURE;
  40. while ((opt = getopt(argc, argv, "c:dei:k:n")) != -1) {
  41. switch (opt) {
  42. case 'c':
  43. if (!(cipher = get_cipher_or_print_error(optarg)))
  44. exit(EXIT_FAILURE);
  45. break;
  46. case 'd':
  47. check_enc_dec(enc);
  48. enc = 0;
  49. break;
  50. case 'e':
  51. check_enc_dec(enc);
  52. enc = 1;
  53. break;
  54. case 'i':
  55. iv = hexstr2buf(optarg, &ivlen);
  56. if (iv == NULL) {
  57. fprintf(stderr, "Error setting IV to %s. The IV should be encoded in hex.\n",
  58. optarg);
  59. exit(EINVAL);
  60. }
  61. memset(optarg, '*', strlen(optarg));
  62. break;
  63. case 'k':
  64. key = hexstr2buf(optarg, &keylen);
  65. if (key == NULL) {
  66. fprintf(stderr, "Error setting key to %s. The key should be encoded in hex.\n",
  67. optarg);
  68. exit(EINVAL);
  69. }
  70. memset(optarg, '*', strlen(optarg));
  71. break;
  72. case 'n':
  73. padding = 0;
  74. break;
  75. default:
  76. show_usage(argv[0]);
  77. exit(EINVAL);
  78. }
  79. }
  80. if (ivlen != get_cipher_ivsize(cipher)) {
  81. fprintf(stderr, "Error: IV must be %d bytes; given IV is %ld bytes.\n",
  82. get_cipher_ivsize(cipher), ivlen);
  83. exit(EXIT_FAILURE);
  84. }
  85. if (keylen != get_cipher_keysize(cipher)) {
  86. fprintf(stderr, "Error: key must be %d bytes; given key is %ld bytes.\n",
  87. get_cipher_keysize(cipher), keylen);
  88. exit(EXIT_FAILURE);
  89. }
  90. ctx = create_ctx(cipher, key, iv, !!enc, padding);
  91. if (ctx) {
  92. ret = do_crypt(stdin, stdout, ctx);
  93. free_ctx(ctx);
  94. }
  95. uencrypt_clear_free(iv, ivlen);
  96. uencrypt_clear_free(key, keylen);
  97. return ret;
  98. }