summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorINAGAKI Hiroshi2025-01-02 05:23:36 +0000
committerINAGAKI Hiroshi2025-01-14 14:00:03 +0000
commit12c0b42231bee58b3cd7cbe95c33de2685484a4f (patch)
tree89e11638a9a957b9edd02ed8621bc2a23ab84b9d
parent4b7638925d3eac03e614e40bc30cb49f5877c46d (diff)
downloadfirmware-utils-12c0b42231bee58b3cd7cbe95c33de2685484a4f.tar.gz
nosimg-enc: add new tool for XikeStor SKS8300 series
Add a new tool to generate a encoded firmware image for XikeStor SKS8300 series devices. In this format, only the first 512 bytes (0x200) are encoded with a fixed patten (length: 0x100). Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/nosimg-enc.c139
2 files changed, 140 insertions, 0 deletions
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 <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#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;
+}