diff --git a/CMakeLists.txt b/CMakeLists.txt index 3352e26..71c604c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ FW_UTIL(motorola-bin "" "" "") FW_UTIL(nand_ecc "" "" "") FW_UTIL(nec-enc "" --std=gnu99 "") FW_UTIL(nec-usbatermfw "" -D_DEFAULT_SOURCE "") +FW_UTIL(nosimg-enc "" --std=gnu99 "") FW_UTIL(osbridge-crc "" "" "") FW_UTIL(oseama src/md5.c "" "") FW_UTIL(otrx "" "" "") diff --git a/src/nosimg-enc.c b/src/nosimg-enc.c new file mode 100644 index 0000000..a806740 --- /dev/null +++ b/src/nosimg-enc.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * nosimg-enc.c - encode/decode "nos.img" image for XikeStor SKS8300 series + */ + +#include +#include +#include +#include +#include +#include + +#define ENCODE_BLKLEN 0x100 +#define ENCODE_BLOCKS 2 + +static const uint8_t key[ENCODE_BLKLEN] = { + 0xee, 0xdd, 0xcc, 0x21, 0x53, 0x55, 0xee, 0xcc, + 0xdd, 0x55, 0x80, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0xcd, 0xbd, 0xdf, 0xae, 0xbb, 0x9b, 0x89, 0x01, + 0x70, 0xe5, 0xcc, 0xdd, 0xf6, 0xfc, 0x83, 0x64, + 0xec, 0xdd, 0xce, 0xf1, 0xe3, 0x54, 0xfe, 0xd0, + 0xbd, 0xab, 0xdd, 0xe1, 0xe4, 0xb4, 0xd5, 0x83, + 0xed, 0xfe, 0xd0, 0xcd, 0xb6, 0x55, 0xcc, 0xa3, + 0xed, 0xd5, 0xc6, 0x7e, 0xdd, 0xcc, 0x21, 0x53, + 0xec, 0x4d, 0xdc, 0x00, 0x53, 0x55, 0xcd, 0xc3, + 0x22, 0x01, 0x80, 0x7e, 0xef, 0xbc, 0x75, 0x66, + 0xa6, 0xc0, 0xcc, 0x2f, 0xfe, 0xd0, 0xee, 0xcc, + 0xdd, 0x55, 0x01, 0x01, 0x01, 0x01, 0xc5, 0x64, + 0x99, 0x45, 0xab, 0x32, 0x55, 0x80, 0x7e, 0xef, + 0x55, 0x80, 0x7e, 0xef, 0xbc, 0x75, 0x66, 0x89, + 0xe3, 0x1d, 0x83, 0xdd, 0xfe, 0x55, 0x8e, 0xab, + 0x7d, 0x55, 0x80, 0x7e, 0xff, 0x01, 0xac, 0x66, + 0x0e, 0xc9, 0x92, 0xd9, 0x73, 0xe5, 0x01, 0x01, + 0xbd, 0xe5, 0x10, 0xce, 0x01, 0x01, 0xba, 0xe8, + 0x3e, 0xdd, 0x81, 0xa1, 0x53, 0x33, 0x01, 0x01, + 0x9a, 0xc5, 0x10, 0xaa, 0x01, 0xce, 0x8a, 0xe1, + 0xb1, 0xfb, 0x00, 0x80, 0x53, 0x77, 0x00, 0x00, + 0x70, 0xdc, 0x00, 0x01, 0x00, 0x00, 0xcb, 0xb1, + 0xa0, 0x30, 0x00, 0x00, 0x55, 0xa6, 0x00, 0x00, + 0xca, 0xbd, 0x01, 0x01, 0x00, 0x00, 0xc9, 0xb2, + 0x81, 0x90, 0x01, 0x00, 0x5a, 0x21, 0x00, 0x01, + 0x79, 0xbc, 0x01, 0x00, 0x78, 0x00, 0x7b, 0xb3, + 0xd4, 0x97, 0x01, 0x00, 0x53, 0x55, 0xa9, 0xfc, + 0xdd, 0xa5, 0x01, 0xbe, 0xaf, 0xc1, 0x75, 0xc5, + 0x8e, 0xd7, 0x77, 0x00, 0x55, 0xd0, 0x0d, 0xac, + 0x01, 0x55, 0x80, 0x7e, 0xef, 0xbc, 0x7e, 0xe6, + 0xf1, 0x6c, 0x52, 0x00, 0x33, 0x16, 0x98, 0xcc, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x79, 0x88, +}; + +static void __attribute__((noreturn)) usage(void) +{ + fprintf(stderr, "Usage: nosimg-enc -i infile -o outfile [-d]\n"); + exit(EXIT_FAILURE); +} + +static void encode_block(uint8_t *data, bool decode) +{ + int i; + + for (i = 0; i < ENCODE_BLKLEN; i++) + data[i] -= key[i] * (decode ? -1 : 1); +} + +int main(int argc, char **argv) +{ + int i, c, n, ret = EXIT_SUCCESS; + char *ifn = NULL, *ofn = NULL; + bool decode = false; + uint8_t buf[0x1000]; + FILE *out, *in; + + while ((c = getopt(argc, argv, "i:o:dh")) != -1) { + switch (c) { + case 'i': + ifn = optarg; + break; + case 'o': + ofn = optarg; + break; + case 'd': + decode = true; + break; + case 'h': + default: + usage(); + } + } + + if (optind != argc || optind == 1) { + fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); + usage(); + } + + in = fopen(ifn, "r"); + if (!in) { + perror("can not open input file"); + usage(); + } + + out = fopen(ofn, "w"); + if (!out) { + perror("can not open output file"); + usage(); + } + + /* encode/decode the first 512 bytes (0x100 x2) */ + for (i = 0; i < ENCODE_BLOCKS; i++) { + n = fread(buf, 1, ENCODE_BLKLEN, in); + if (n < ENCODE_BLKLEN) { + fprintf(stderr, + "failed to read data for encoding/decoding\n"); + ret = EXIT_FAILURE; + goto out; + } + + encode_block(buf, decode); + fwrite(buf, 1, ENCODE_BLKLEN, out); + } + + /* copy the remaining data */ + while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { + if (fwrite(buf, 1, n, out) != n) { + fprintf(stderr, "failed to write"); + ret = EXIT_FAILURE; + goto out; + } + } + + if (ferror(in)) { + perror("failed to read"); + ret = EXIT_FAILURE; + } + +out: + fclose(in); + fclose(out); + return ret; +}