1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * nec-enc.c - encode/decode nec firmware with key 4 * 5 * based on xorimage.c in OpenWrt 6 * 7 */ 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <stdint.h> 13 #include <unistd.h> 14 15 #define KEY_LEN 16 16 #define PATTERN_LEN 251 17 18 static int 19 xor_pattern(uint8_t *data, size_t len, const char *key, int k_len, int k_off) 20 { 21 int offset = k_off; 22 23 while (len--) { 24 *data ^= key[offset]; 25 data++; 26 offset = (offset + 1) % k_len; 27 } 28 29 return offset; 30 } 31 32 static void xor_data(uint8_t *data, size_t len, const uint8_t *pattern) 33 { 34 for (int i = 0; i < len; i++) { 35 *data ^= pattern[i]; 36 data++; 37 } 38 } 39 40 static void __attribute__((noreturn)) usage(void) 41 { 42 fprintf(stderr, "Usage: nec-enc -i infile -o outfile -k <key>\n"); 43 exit(EXIT_FAILURE); 44 } 45 46 static unsigned char buf_pattern[4096], buf[4096]; 47 48 int main(int argc, char **argv) 49 { 50 int k_off = 0, ptn = 1, c, ret = EXIT_SUCCESS; 51 char *ifn = NULL, *ofn = NULL, *key = NULL; 52 size_t n, k_len; 53 FILE *out, *in; 54 55 while ((c = getopt(argc, argv, "i:o:k:h")) != -1) { 56 switch (c) { 57 case 'i': 58 ifn = optarg; 59 break; 60 case 'o': 61 ofn = optarg; 62 break; 63 case 'k': 64 key = optarg; 65 break; 66 case 'h': 67 default: 68 usage(); 69 } 70 } 71 72 if (optind != argc || optind == 1) { 73 fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); 74 usage(); 75 } 76 77 in = fopen(ifn, "r"); 78 if (!in) { 79 perror("can not open input file"); 80 usage(); 81 } 82 83 out = fopen(ofn, "w"); 84 if (!out) { 85 perror("can not open output file"); 86 usage(); 87 } 88 89 if (!key) { 90 fprintf(stderr, "key is not specified\n"); 91 usage(); 92 } 93 94 k_len = strnlen(key, KEY_LEN + 1); 95 if (k_len == 0 || k_len > KEY_LEN) { 96 fprintf(stderr, "key length is not in range (0,%d)\n", KEY_LEN); 97 usage(); 98 } 99 100 while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { 101 for (int i = 0; i < n; i++) { 102 buf_pattern[i] = ptn; 103 ptn++; 104 105 if (ptn > PATTERN_LEN) 106 ptn = 1; 107 } 108 109 k_off = xor_pattern(buf_pattern, n, key, k_len, k_off); 110 xor_data(buf, n, buf_pattern); 111 112 if (fwrite(buf, 1, n, out) != n) { 113 perror("failed to write"); 114 ret = EXIT_FAILURE; 115 goto out; 116 } 117 } 118 119 if (ferror(in)) { 120 perror("failed to read"); 121 ret = EXIT_FAILURE; 122 goto out; 123 } 124 125 out: 126 fclose(in); 127 fclose(out); 128 return ret; 129 } 130
This page was automatically generated by LXR 0.3.1. • OpenWrt