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

Sources/firmware-utils/src/xorimage.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * xorimage.c - partially based on OpenWrt's addpattern.c
  4  */
  5 
  6 
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 #include <string.h>
 10 #include <stdbool.h>
 11 #include <stdint.h>
 12 #include <unistd.h>
 13 #include <sys/stat.h>
 14 
 15 static char default_pattern[] = "12345678";
 16 static int is_hex_pattern;
 17 
 18 
 19 int xor_data(void *data, size_t len, const void *pattern, int p_len, int p_off)
 20 {
 21         const uint8_t *key = pattern;
 22         uint8_t *d = data;
 23 
 24         while (len--) {
 25                 *d ^= key[p_off];
 26                 d++;
 27                 p_off = (p_off + 1) % p_len;
 28         }
 29         return p_off;
 30 }
 31 
 32 
 33 void usage(void) __attribute__ (( __noreturn__ ));
 34 
 35 void usage(void)
 36 {
 37         fprintf(stderr, "Usage: xorimage [-i infile] [-o outfile] [-p <pattern>] [-x]\n");
 38         exit(EXIT_FAILURE);
 39 }
 40 
 41 
 42 int main(int argc, char **argv)
 43 {
 44         char buf[1024]; /* keep this at 1k or adjust garbage calc below */
 45         FILE *in = stdin;
 46         FILE *out = stdout;
 47         char *ifn = NULL;
 48         char *ofn = NULL;
 49         const char *pattern = default_pattern;
 50         char hex_pattern[128];
 51         unsigned int hex_buf;
 52         int c;
 53         size_t n;
 54         int p_len, p_off = 0;
 55 
 56         while ((c = getopt(argc, argv, "i:o:p:xh")) != -1) {
 57                 switch (c) {
 58                         case 'i':
 59                                 ifn = optarg;
 60                                 break;
 61                         case 'o':
 62                                 ofn = optarg;
 63                                 break;
 64                         case 'p':
 65                                 pattern = optarg;
 66                                 break;
 67                         case 'x':
 68                                 is_hex_pattern = true;
 69                                 break;
 70                         case 'h':
 71                         default:
 72                                 usage();
 73                 }
 74         }
 75 
 76         if (optind != argc || optind == 1) {
 77                 fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]);
 78                 usage();
 79         }
 80 
 81         if (ifn && !(in = fopen(ifn, "r"))) {
 82                 fprintf(stderr, "can not open \"%s\" for reading\n", ifn);
 83                 usage();
 84         }
 85 
 86         if (ofn && !(out = fopen(ofn, "w"))) {
 87                 fprintf(stderr, "can not open \"%s\" for writing\n", ofn);
 88                 usage();
 89         }
 90 
 91         p_len = strlen(pattern);
 92 
 93         if (p_len == 0) {
 94                 fprintf(stderr, "pattern cannot be empty\n");
 95                 usage();
 96         }
 97 
 98         if (is_hex_pattern) {
 99                 int i;
100 
101                 if ((p_len / 2) > sizeof(hex_pattern)) {
102                         fprintf(stderr, "provided hex pattern is too long\n");
103                         usage();
104                 }
105 
106                 if (p_len % 2 != 0) {
107                         fprintf(stderr, "the number of characters (hex) is incorrect\n");
108                         usage();
109                 }
110 
111                 for (i = 0; i < (p_len / 2); i++) {
112                         if (sscanf(pattern + (i * 2), "%2x", &hex_buf) < 0) {
113                                 fprintf(stderr, "invalid hex digit around %d\n", i * 2);
114                                 usage();
115                         }
116                         hex_pattern[i] = (char)hex_buf;
117                 }
118         }
119 
120         while ((n = fread(buf, 1, sizeof(buf), in)) > 0) {
121                 if (n < sizeof(buf)) {
122                         if (ferror(in)) {
123                         FREAD_ERROR:
124                                 fprintf(stderr, "fread error\n");
125                                 return EXIT_FAILURE;
126                         }
127                 }
128 
129                 if (is_hex_pattern) {
130                         p_off = xor_data(buf, n, hex_pattern, (p_len / 2),
131                                          p_off);
132                 } else {
133                         p_off = xor_data(buf, n, pattern, p_len, p_off);
134                 }
135 
136                 if (!fwrite(buf, n, 1, out)) {
137                 FWRITE_ERROR:
138                         fprintf(stderr, "fwrite error\n");
139                         return EXIT_FAILURE;
140                 }
141         }
142 
143         if (ferror(in)) {
144                 goto FREAD_ERROR;
145         }
146 
147         if (fflush(out)) {
148                 goto FWRITE_ERROR;
149         }
150 
151         fclose(in);
152         fclose(out);
153 
154         return EXIT_SUCCESS;
155 }
156 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt