• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/buffalo-enc.c

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <stdint.h>
  9 #include <string.h>
 10 #include <libgen.h>
 11 #include <getopt.h>     /* for getopt() */
 12 #include <stdarg.h>
 13 
 14 #include "buffalo-lib.h"
 15 
 16 #define ERR(fmt, args...) do { \
 17         fflush(0); \
 18         fprintf(stderr, "[%s] *** error: " fmt "\n", \
 19                         progname, ## args ); \
 20 } while (0)
 21 
 22 static char *progname;
 23 static char *ifname;
 24 static char *ofname;
 25 static char *crypt_key = "Buffalo";
 26 static char *magic = "start";
 27 static int longstate;
 28 static unsigned char seed = 'O';
 29 
 30 static char *product;
 31 static char *version;
 32 static int do_decrypt;
 33 static int offset;
 34 static int size;
 35 
 36 void usage(int status)
 37 {
 38         FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
 39 
 40         fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
 41         fprintf(stream,
 42 "\n"
 43 "Options:\n"
 44 "  -d              decrypt instead of encrypt\n"
 45 "  -i <file>       read input from the file <file>\n"
 46 "  -o <file>       write output to the file <file>\n"
 47 "  -l              use longstate {en,de}cryption method\n"
 48 "  -k <key>        use <key> for encryption (default: Buffalo)\n"
 49 "  -m <magic>      set magic to <magic>\n"
 50 "  -p <product>    set product name to <product>\n"
 51 "  -v <version>    set version to <version>\n"
 52 "  -h              show this screen\n"
 53 "  -O              Offset of encrypted data in file (decryption)\n"
 54 "  -S              Size of unencrypted data in file (encryption)\n"
 55         );
 56 
 57         exit(status);
 58 }
 59 
 60 static int decrypt_file(void)
 61 {
 62         struct enc_param ep;
 63         ssize_t src_len;
 64         unsigned char *buf = NULL;
 65         int err;
 66         int ret = -1;
 67 
 68         src_len = get_file_size(ifname);
 69         if (src_len < 0) {
 70                 ERR("unable to get size of '%s'", ifname);
 71                 goto out;
 72         }
 73 
 74         buf = malloc(src_len);
 75         if (buf == NULL) {
 76                 ERR("no memory for the buffer");
 77                 goto out;
 78         }
 79 
 80         err = read_file_to_buf(ifname, buf, src_len);
 81         if (err) {
 82                 ERR("unable to read from file '%s'", ifname);
 83                 goto out;
 84         }
 85 
 86         memset(&ep, '\0', sizeof(ep));
 87         ep.key = (unsigned char *) crypt_key;
 88         ep.longstate = longstate;
 89 
 90         err = decrypt_buf(&ep, buf + offset, src_len - offset);
 91         if (err) {
 92                 ERR("unable to decrypt '%s'", ifname);
 93                 goto out;
 94         }
 95 
 96         printf("Magic\t\t: '%s'\n", ep.magic);
 97         printf("Seed\t\t: 0x%02x\n", ep.seed);
 98         printf("Product\t\t: '%s'\n", ep.product);
 99         printf("Version\t\t: '%s'\n", ep.version);
100         printf("Data len\t: %u\n", ep.datalen);
101         printf("Checksum\t: 0x%08x\n", ep.csum);
102 
103         err = write_buf_to_file(ofname, buf + offset, ep.datalen);
104         if (err) {
105                 ERR("unable to write to file '%s'", ofname);
106                 goto out;
107         }
108 
109         ret = 0;
110 
111 out:
112         free(buf);
113         return ret;
114 }
115 
116 static int encrypt_file(void)
117 {
118         struct enc_param ep;
119         ssize_t src_len, tail_dst, tail_len, tail_src;
120         unsigned char *buf;
121         uint32_t hdrlen;
122         ssize_t totlen = 0;
123         int err;
124         int ret = -1;
125 
126         src_len = get_file_size(ifname);
127         if (src_len < 0) {
128                 ERR("unable to get size of '%s'", ifname);
129                 goto out;
130         }
131 
132         if (size) {
133                 tail_dst = enc_compute_buf_len(product, version, size);
134                 tail_len = src_len - size;
135                 totlen = tail_dst + tail_len;
136         } else
137                 totlen = enc_compute_buf_len(product, version, src_len);
138 
139         buf = malloc(totlen);
140         if (buf == NULL) {
141                 ERR("no memory for the buffer");
142                 goto out;
143         }
144 
145         hdrlen = enc_compute_header_len(product, version);
146 
147         err = read_file_to_buf(ifname, &buf[hdrlen], src_len);
148         if (err) {
149                 ERR("unable to read from file '%s'", ofname);
150                 goto free_buf;
151         }
152 
153         if (size) {
154                 tail_src = hdrlen + size;
155                 memmove(&buf[tail_dst], &buf[tail_src], tail_len);
156                 memset(&buf[tail_src], 0, tail_dst - tail_src);
157                 src_len = size;
158         }
159 
160         memset(&ep, '\0', sizeof(ep));
161         ep.key = (unsigned char *) crypt_key;
162         ep.seed = seed;
163         ep.longstate = longstate;
164         ep.csum = buffalo_csum(src_len, &buf[hdrlen], src_len);
165         ep.datalen = src_len;
166         strcpy((char *) ep.magic, magic);
167         strcpy((char *) ep.product, product);
168         strcpy((char *) ep.version, version);
169 
170         err = encrypt_buf(&ep, buf, &buf[hdrlen]);
171         if (err) {
172                 ERR("invalid input file");
173                 goto free_buf;
174         }
175 
176         err = write_buf_to_file(ofname, buf, totlen);
177         if (err) {
178                 ERR("unable to write to file '%s'", ofname);
179                 goto free_buf;
180         }
181 
182         ret = 0;
183 
184 free_buf:
185         free(buf);
186 out:
187         return ret;
188 }
189 
190 static int check_params(void)
191 {
192         int ret = -1;
193 
194         if (ifname == NULL) {
195                 ERR("no input file specified");
196                 goto out;
197         }
198 
199         if (ofname == NULL) {
200                 ERR("no output file specified");
201                 goto out;
202         }
203 
204         if (crypt_key == NULL) {
205                 ERR("no key specified");
206                 goto out;
207         } else if (strlen(crypt_key) > BCRYPT_MAX_KEYLEN) {
208                 ERR("key '%s' is too long", crypt_key);
209                 goto out;
210         }
211 
212         if (strlen(magic) != (ENC_MAGIC_LEN - 1)) {
213                 ERR("length of magic must be %d", ENC_MAGIC_LEN - 1);
214                 goto out;
215         }
216 
217         if (!do_decrypt) {
218                 if (product == NULL) {
219                         ERR("no product specified");
220                         goto out;
221                 }
222 
223                 if (version == NULL) {
224                         ERR("no version specified");
225                         goto out;
226                 }
227 
228                 if (strlen(product) > (ENC_PRODUCT_LEN - 1)) {
229                         ERR("product name '%s' is too long", product);
230                         goto out;
231                 }
232 
233                 if (strlen(version) > (ENC_VERSION_LEN - 1)) {
234                         ERR("version '%s' is too long", version);
235                         goto out;
236                 }
237         }
238 
239         ret = 0;
240 
241 out:
242         return ret;
243 }
244 
245 int main(int argc, char *argv[])
246 {
247         int res = EXIT_FAILURE;
248         int err;
249 
250         progname = basename(argv[0]);
251 
252         while ( 1 ) {
253                 int c;
254 
255                 c = getopt(argc, argv, "adi:m:o:hlp:v:k:O:r:s:S:");
256                 if (c == -1)
257                         break;
258 
259                 switch (c) {
260                 case 'd':
261                         do_decrypt = 1;
262                         break;
263                 case 'i':
264                         ifname = optarg;
265                         break;
266                 case 'l':
267                         longstate = 1;
268                         break;
269                 case 'm':
270                         magic = optarg;
271                         break;
272                 case 'o':
273                         ofname = optarg;
274                         break;
275                 case 'p':
276                         product = optarg;
277                         break;
278                 case 'v':
279                         version = optarg;
280                         break;
281                 case 'k':
282                         crypt_key = optarg;
283                         break;
284                 case 's':
285                         seed = strtoul(optarg, NULL, 16);
286                         break;
287                 case 'O':
288                         offset = strtoul(optarg, NULL, 0);
289                         break;
290                 case 'S':
291                         size = strtoul(optarg, NULL, 0);
292                         break;
293                 case 'h':
294                         usage(EXIT_SUCCESS);
295                         break;
296                 default:
297                         usage(EXIT_FAILURE);
298                         break;
299                 }
300         }
301 
302         err = check_params();
303         if (err)
304                 goto out;
305 
306         if (do_decrypt)
307                 err = decrypt_file();
308         else
309                 err = encrypt_file();
310 
311         if (err)
312                 goto out;
313 
314         res = EXIT_SUCCESS;
315 
316 out:
317         return res;
318 }
319 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt