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