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

Sources/firmware-utils/src/spw303v.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * spw303v.c - partially based on OpenWrt's imagetag.c and addpattern.c
  4  *
  5  * Copyright (C) 2011  Jonas Gorski <jonas.gorski@gmail.com>
  6  */
  7 
  8 #include <arpa/inet.h>
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <string.h>
 12 #include <stdint.h>
 13 #include <unistd.h>
 14 #include <sys/stat.h>
 15 
 16 #define IMAGE_LEN 10                   /* Length of Length Field */
 17 #define ADDRESS_LEN 12                 /* Length of Address field */
 18 #define TAGID_LEN  6                   /* Length of tag ID */
 19 #define TAGINFO_LEN 20                 /* Length of vendor information field in tag */
 20 #define TAGVER_LEN 4                   /* Length of Tag Version */
 21 #define TAGLAYOUT_LEN 4                /* Length of FlashLayoutVer */
 22 
 23 
 24 struct spw303v_tag
 25 {
 26     unsigned char tagVersion[4];       // tag version.  Will be 2 here.
 27     unsigned char signiture_1[20];                       // text line for company info
 28     unsigned char signiture_2[14];                      // additional info (can be version number)
 29     unsigned char chipId[6];                                    // chip id
 30     unsigned char boardId[16];                          // board id
 31     unsigned char bigEndian[2];                         // if = 1 - big, = 0 - little endia of the host
 32     unsigned char totalImageLen[IMAGE_LEN];      // the sum of all the following length
 33     unsigned char cfeAddress[ADDRESS_LEN];       // if non zero, cfe starting address
 34     unsigned char cfeLen[IMAGE_LEN];             // if non zero, cfe size in clear ASCII text.
 35     unsigned char rootfsAddress[ADDRESS_LEN];    // if non zero, filesystem starting address
 36     unsigned char rootfsLen[IMAGE_LEN];          // if non zero, filesystem size in clear ASCII text.
 37     unsigned char kernelAddress[ADDRESS_LEN];    // if non zero, kernel starting address
 38     unsigned char kernelLen[IMAGE_LEN];          // if non zero, kernel size in clear ASCII text.
 39 
 40         unsigned char certf1Address[ADDRESS_LEN];
 41         unsigned char certf1Len[6];
 42         unsigned char certf2Address[ADDRESS_LEN];
 43         unsigned char certf2Len[6];
 44         unsigned char certf3Address[ADDRESS_LEN];
 45         unsigned char certf3Len[6];
 46         unsigned char httpsFileSize[4];
 47         unsigned char tr64FileSize[4];
 48         unsigned char tr69FileSize[4];
 49         unsigned char filesmap[4];
 50 
 51     unsigned char imageSequence[4];                             // incrments everytime an image is flashed
 52     unsigned char reserved[4];                                      // reserved for later use
 53     unsigned char imageCRC[4];                      // 216-219: CRC32 of images
 54     unsigned char reserved2[16];                    // 220-235: Unused at present
 55     unsigned char headerCRC[4];                     // 236-239: CRC32 of header excluding tagVersion
 56     unsigned char reserved3[16];                    // 240-255: Unused at present
 57 };
 58 
 59 static uint32_t crc32tab[256] = {
 60         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
 61         0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
 62         0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
 63         0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
 64         0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
 65         0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
 66         0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
 67         0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
 68         0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
 69         0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
 70         0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
 71         0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
 72         0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
 73         0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
 74         0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
 75         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
 76         0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
 77         0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
 78         0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
 79         0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
 80         0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
 81         0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
 82         0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
 83         0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
 84         0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
 85         0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
 86         0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
 87         0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
 88         0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
 89         0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
 90         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
 91         0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
 92 };
 93 #define IMAGETAG_CRC_START                      0xFFFFFFFF
 94 
 95 #define IMAGETAG_MAGIC1_TCOM            "AAAAAAAA Corporatio"
 96 
 97 static char fake_data[] = {
 98         0x18, 0x21, 0x21, 0x18, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 ,0x18,
 99         0x21, 0x24, 0x21, 0x1b, 0x18, 0x18, 0x24, 0x24, 0x18, 0x21, 0x21, 0x21,
100         0x21, 0x21, 0x21, 0x21, 0x1b, 0x18, 0x18, 0x24, 0x24, 0x21, 0x21, 0x21,
101         0x21, 0x21, 0x21, 0x21, 0x18, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x18,
102         0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x18, 0x21, 0x21,
103         0x21, 0x21, 0x21, 0x21,
104 };
105 
106 
107 uint32_t crc32(uint32_t crc, const void *data, size_t len)
108 {
109         const uint8_t *in = data;
110 
111         while (len--)
112                 crc = (crc >> 8) ^ crc32tab[(crc ^ *in++) & 0xFF];
113 
114         return crc;
115 }
116 
117 void fix_header(void *buf)
118 {
119         struct spw303v_tag *tag = buf;
120         uint32_t crc;
121         /* Replace signature with custom t-com one */
122         memset(tag->signiture_1, 0, 20);
123         memcpy(tag->signiture_1, IMAGETAG_MAGIC1_TCOM, strlen(IMAGETAG_MAGIC1_TCOM));
124 
125         /* Clear cert fields to remove information_* data */
126         memset(tag->certf1Address, 0, 74);
127 
128         /* replace image crc with modified one */
129         crc = ntohl(*((uint32_t *)&tag->imageCRC));
130 
131         crc = htonl(crc32(crc, fake_data, 64));
132 
133         memcpy(tag->imageCRC, &crc, 4);
134 
135         /* Update tag crc */
136         crc = htonl(crc32(IMAGETAG_CRC_START, buf, 236));
137         memcpy(tag->headerCRC, &crc, 4);
138 }
139 
140 
141 
142 void usage(void) __attribute__ (( __noreturn__ ));
143 
144 void usage(void)
145 {
146         fprintf(stderr, "Usage: spw303v [-i <inputfile>] [-o <outputfile>]\n");
147         exit(EXIT_FAILURE);
148 }
149 
150 
151 int main(int argc, char **argv)
152 {
153         char buf[1024]; /* keep this at 1k or adjust garbage calc below */
154         FILE *in = stdin;
155         FILE *out = stdout;
156         char *ifn = NULL;
157         char *ofn = NULL;
158         int c;
159         size_t n;
160         int first_block = 1;
161 
162         uint32_t image_crc = IMAGETAG_CRC_START;
163 
164         while ((c = getopt(argc, argv, "i:o:h")) != -1) {
165                 switch (c) {
166                         case 'i':
167                                 ifn = optarg;
168                                 break;
169                         case 'o':
170                                 ofn = optarg;
171                                 break;
172                         case 'h':
173                         default:
174                                 usage();
175                 }
176         }
177 
178         if (optind != argc || optind == 1) {
179                 fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]);
180                 usage();
181         }
182 
183         if (ifn && !(in = fopen(ifn, "r"))) {
184                 fprintf(stderr, "can not open \"%s\" for reading\n", ifn);
185                 usage();
186         }
187 
188         if (ofn && !(out = fopen(ofn, "w"))) {
189                 fprintf(stderr, "can not open \"%s\" for writing\n", ofn);
190                 usage();
191         }
192 
193 
194 
195         while ((n = fread(buf, 1, sizeof(buf), in)) > 0) {
196                 if (n < sizeof(buf)) {
197                         if (ferror(in)) {
198                         FREAD_ERROR:
199                                 fprintf(stderr, "fread error\n");
200                                 return EXIT_FAILURE;
201                         }
202                 }
203 
204                 if (first_block && n >= 256) {
205                         fix_header(buf);
206                         first_block = 0;
207                 }
208 
209                 image_crc = crc32(image_crc, buf, n);
210 
211                 if (!fwrite(buf, n, 1, out)) {
212                 FWRITE_ERROR:
213                         fprintf(stderr, "fwrite error\n");
214                         return EXIT_FAILURE;
215                 }
216         }
217 
218         if (ferror(in)) {
219                 goto FREAD_ERROR;
220         }
221 
222         if (fflush(out)) {
223                 goto FWRITE_ERROR;
224         }
225 
226         fclose(in);
227         fclose(out);
228 
229         return EXIT_SUCCESS;
230 }
231 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt