uencrypt: add package to decrypt WG4хх223 config
[openwrt/staging/noltari.git] / package / utils / uencrypt / src / uencrypt.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2 * Copyright (C) 2022 Eneas Ulir de Queiroz
3 */
4
5 #include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9
10 #ifdef USE_WOLFSSL
11 # include <wolfssl/options.h>
12 # include <wolfssl/openssl/evp.h>
13 #else
14 # include <openssl/evp.h>
15 #endif
16
17 int do_crypt(FILE *infile, FILE *outfile, const char *key, const char *iv,
18 int enc, int padding)
19 {
20 EVP_CIPHER_CTX *ctx;
21 unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
22 int inlen, outlen;
23
24 ctx = EVP_CIPHER_CTX_new();
25 EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, enc);
26 EVP_CIPHER_CTX_set_padding(ctx, padding);
27
28 for (;;) {
29 inlen = fread(inbuf, 1, 1024, infile);
30 if (inlen <= 0)
31 break;
32 if (!EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen)) {
33 EVP_CIPHER_CTX_free(ctx);
34 return -1;
35 }
36 fwrite(outbuf, 1, outlen, outfile);
37 }
38 if (!EVP_CipherFinal_ex(ctx, outbuf, &outlen)) {
39 EVP_CIPHER_CTX_free(ctx);
40 return -1;
41 }
42 fwrite(outbuf, 1, outlen, outfile);
43
44 EVP_CIPHER_CTX_free(ctx);
45 return 0;
46 }
47
48 static void check_enc_dec(const int enc)
49 {
50 if (enc == -1)
51 return;
52 fprintf(stderr, "Error: both -d and -e were specified.\n");
53 exit(EXIT_FAILURE);
54 }
55
56 static void show_usage(const char* name)
57 {
58 fprintf(stderr, "Usage: %s: [-d | -e] [-n] -k key -i iv\n"
59 "-d = decrypt; -e = encrypt; -n = no padding\n", name);
60 }
61
62 int main(int argc, char *argv[])
63 {
64 int enc = -1;
65 unsigned char *iv = NULL;
66 unsigned char *key = NULL;
67 long len;
68 int opt;
69 int padding = 1;
70 int ret;
71
72 while ((opt = getopt(argc, argv, "dei:k:n")) != -1) {
73 switch (opt) {
74 case 'd':
75 check_enc_dec(enc);
76 enc = 0;
77 break;
78 case 'e':
79 check_enc_dec(enc);
80 enc = 1;
81 break;
82 case 'i':
83 iv = OPENSSL_hexstr2buf((const char *)optarg, &len);
84 if (iv == NULL || len != 16) {
85 fprintf(stderr, "Error setting IV to %s. The IV should be 16 bytes, encoded in hex.\n",
86 optarg);
87 exit(EINVAL);
88 }
89 break;
90 case 'k':
91 key = OPENSSL_hexstr2buf((const char *)optarg, &len);
92 if (key == NULL || len != 16) {
93 fprintf(stderr, "Error setting key to %s. The key should be 16 bytes, encoded in hex.\n",
94 optarg);
95 exit(EINVAL);
96 }
97 break;
98 case 'n':
99 padding = 0;
100 break;
101 default:
102 show_usage(argv[0]);
103 exit(EINVAL);
104 }
105 }
106 if (iv == NULL || key == NULL) {
107 fprintf(stderr, "Error: %s not set.\n", key ? "iv" : (iv ? "key" : "key and iv"));
108 show_usage(argv[0]);
109 exit(EXIT_FAILURE);
110 }
111 ret = do_crypt(stdin, stdout, key, iv, !!enc, padding);
112 if (ret)
113 fprintf(stderr, "Error during crypt operation.\n");
114 OPENSSL_free(iv);
115 OPENSSL_free(key);
116 return ret;
117 }