firmware-utils: add hex pattern mode for xorimage
authorINAGAKI Hiroshi <musashino.open@gmail.com>
Sat, 8 Dec 2018 06:07:52 +0000 (15:07 +0900)
committerChristian Lamparter <chunkeey@gmail.com>
Mon, 24 Dec 2018 18:18:07 +0000 (19:18 +0100)
This commit adds "hex pattern mode" to xorimage. This mode allows xor
with a hexadecimal pattern that cannot be expressed with ASCII
charactors.

usage (example):
  xorimage -i firmware.bin -o firmware.bin.new -p 6A57190601121E4C -x

Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com> (fix checkpatch)
tools/firmware-utils/src/xorimage.c

index ca6e437..2ca643f 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <unistd.h>
 #include <sys/stat.h>
 
 static char default_pattern[] = "12345678";
+static int is_hex_pattern;
 
 
 int xor_data(uint8_t *data, size_t len, const uint8_t *pattern, int p_len, int p_off)
@@ -43,7 +45,7 @@ void usage(void) __attribute__ (( __noreturn__ ));
 
 void usage(void)
 {
-       fprintf(stderr, "Usage: xorimage [-i infile] [-o outfile] [-p <pattern>]\n");
+       fprintf(stderr, "Usage: xorimage [-i infile] [-o outfile] [-p <pattern>] [-x]\n");
        exit(EXIT_FAILURE);
 }
 
@@ -56,12 +58,14 @@ int main(int argc, char **argv)
        char *ifn = NULL;
        char *ofn = NULL;
        const char *pattern = default_pattern;
+       char hex_pattern[128];
+       unsigned int hex_buf;
        int c;
        int v0, v1, v2;
        size_t n;
        int p_len, p_off = 0;
 
-       while ((c = getopt(argc, argv, "i:o:p:h")) != -1) {
+       while ((c = getopt(argc, argv, "i:o:p:xh")) != -1) {
                switch (c) {
                        case 'i':
                                ifn = optarg;
@@ -72,6 +76,9 @@ int main(int argc, char **argv)
                        case 'p':
                                pattern = optarg;
                                break;
+                       case 'x':
+                               is_hex_pattern = true;
+                               break;
                        case 'h':
                        default:
                                usage();
@@ -100,6 +107,27 @@ int main(int argc, char **argv)
                usage();
        }
 
+       if (is_hex_pattern) {
+               int i;
+
+               if ((p_len / 2) > sizeof(hex_pattern)) {
+                       fprintf(stderr, "provided hex pattern is too long\n");
+                       usage();
+               }
+
+               if (p_len % 2 != 0) {
+                       fprintf(stderr, "the number of characters (hex) is incorrect\n");
+                       usage();
+               }
+
+               for (i = 0; i < (p_len / 2); i++) {
+                       if (sscanf(pattern + (i * 2), "%2x", &hex_buf) < 0) {
+                               fprintf(stderr, "invalid hex digit around %d\n", i * 2);
+                               usage();
+                       }
+                       hex_pattern[i] = (char)hex_buf;
+               }
+       }
 
        while ((n = fread(buf, 1, sizeof(buf), in)) > 0) {
                if (n < sizeof(buf)) {
@@ -110,7 +138,12 @@ int main(int argc, char **argv)
                        }
                }
 
-               p_off = xor_data(buf, n, pattern, p_len, p_off);
+               if (is_hex_pattern) {
+                       p_off = xor_data(buf, n, hex_pattern, (p_len / 2),
+                                        p_off);
+               } else {
+                       p_off = xor_data(buf, n, pattern, p_len, p_off);
+               }
 
                if (!fwrite(buf, n, 1, out)) {
                FWRITE_ERROR: