uencrypt-openssl.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* SPDX-License-Identifier: GPL-2.0-or-later
  2. * Copyright (C) 2022-2023 Eneas Ulir de Queiroz
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include "uencrypt.h"
  9. const cipher_t *get_default_cipher(void)
  10. {
  11. return EVP_aes_128_cbc();
  12. }
  13. #ifndef USE_WOLFSSL
  14. static void print_ciphers(const OBJ_NAME *name,void *arg) {
  15. fprintf(arg, "\t%s\n", name->name);
  16. }
  17. #endif
  18. const cipher_t *get_cipher_or_print_error(char *name)
  19. {
  20. const EVP_CIPHER *cipher;
  21. if ((cipher = EVP_get_cipherbyname(name)))
  22. return cipher;
  23. fprintf(stderr, "Error: invalid cipher: %s.\n", name);
  24. #ifndef USE_WOLFSSL
  25. fprintf(stderr, "Supported ciphers: \n");
  26. OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, print_ciphers, stderr);
  27. #endif
  28. return NULL;
  29. }
  30. int get_cipher_ivsize(const cipher_t *cipher)
  31. {
  32. return EVP_CIPHER_iv_length(cipher);
  33. }
  34. int get_cipher_keysize(const cipher_t *cipher)
  35. {
  36. return EVP_CIPHER_key_length(cipher);
  37. }
  38. ctx_t *create_ctx(const cipher_t *cipher, const unsigned char *key,
  39. const unsigned char *iv, int enc, int padding)
  40. {
  41. EVP_CIPHER_CTX *ctx;
  42. int ret;
  43. ctx = EVP_CIPHER_CTX_new();
  44. if (!ctx) {
  45. fprintf (stderr, "Error: create_ctx: out of memory.\n");
  46. return NULL;
  47. }
  48. ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
  49. if (!ret) {
  50. fprintf(stderr, "Error:EVP_CipherInit_ex: %d\n", ret);
  51. goto abort;
  52. }
  53. ret = EVP_CIPHER_CTX_set_padding(ctx, padding);
  54. if (!ret) {
  55. fprintf(stderr, "Error:EVP_CIPHER_CTX_set_padding: %d\n", ret);
  56. goto abort;
  57. }
  58. return ctx;
  59. abort:
  60. free_ctx(ctx);
  61. return NULL;
  62. }
  63. int do_crypt(FILE *infile, FILE *outfile, ctx_t *ctx)
  64. {
  65. unsigned char inbuf[CRYPT_BUF_SIZE];
  66. unsigned char outbuf[CRYPT_BUF_SIZE + EVP_MAX_BLOCK_LENGTH];
  67. int inlen, outlen;
  68. int ret;
  69. for (;;) {
  70. inlen = fread(inbuf, 1, CRYPT_BUF_SIZE, infile);
  71. if (inlen <= 0)
  72. break;
  73. ret = EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen);
  74. if (!ret) {
  75. fprintf(stderr, "Error: EVP_CipherUpdate: %d\n", ret);
  76. return ret;
  77. }
  78. ret = fwrite(outbuf, 1, outlen, outfile);
  79. if (ret != outlen) {
  80. fprintf(stderr, "Error: CipherUpdate short write.\n");
  81. return ret - outlen;
  82. }
  83. }
  84. ret = EVP_CipherFinal_ex(ctx, outbuf, &outlen);
  85. if (!ret) {
  86. fprintf(stderr, "Error: EVP_CipherFinal: %d\n", ret);
  87. return ret;
  88. }
  89. ret = fwrite(outbuf, 1, outlen, outfile);
  90. if (ret != outlen) {
  91. fprintf(stderr, "Error: CipherFinal short write.\n");
  92. return ret - outlen;
  93. }
  94. return 0;
  95. }
  96. void free_ctx(ctx_t *ctx)
  97. {
  98. EVP_CIPHER_CTX_free(ctx);
  99. }