Skip to content

Commit 07471a7

Browse files
committed
Since the nina-fw OTA has been rewritten to directly download the OTA binary we've got to take the OTA header at the start of the update file into account. This has the added benefit of being able to evaluate the CRC before we flash the image to the microcontroller flash.
1 parent 9b8098f commit 07471a7

File tree

4 files changed

+2782
-2475
lines changed

4 files changed

+2782
-2475
lines changed

libraries/SNU/extras/NiNaBoot/NiNaBoot.ino

+95
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,55 @@
3838
const char * UPDATE_FILE_NAME = "/fs/UPDATE.BIN";
3939
const char * UPDATE_FILE_NAME_LZSS = "/fs/UPDATE.BIN.LZSS";
4040

41+
static const uint32_t crc_table[256] = {
42+
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
43+
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
44+
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
45+
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
46+
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
47+
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
48+
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
49+
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
50+
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
51+
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
52+
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
53+
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
54+
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
55+
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
56+
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
57+
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
58+
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
59+
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
60+
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
61+
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
62+
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
63+
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
64+
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
65+
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
66+
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
67+
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
68+
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
69+
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
70+
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
71+
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
72+
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
73+
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
74+
};
75+
76+
uint32_t crc_update(uint32_t crc, const void * data, size_t data_len)
77+
{
78+
const unsigned char *d = (const unsigned char *)data;
79+
unsigned int tbl_idx;
80+
81+
while (data_len--) {
82+
tbl_idx = (crc ^ *d) & 0xff;
83+
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
84+
d++;
85+
}
86+
87+
return crc & 0xffffffff;
88+
}
89+
4190
FlashClass flash;
4291

4392
// Initialize C library
@@ -73,6 +122,52 @@ int main() {
73122
if (WiFiStorage.exists(UPDATE_FILE_NAME_LZSS))
74123
{
75124
WiFiStorageFile update_file = WiFiStorage.open(UPDATE_FILE_NAME_LZSS);
125+
126+
union
127+
{
128+
struct __attribute__((packed))
129+
{
130+
uint32_t len;
131+
uint32_t crc32;
132+
} header;
133+
uint8_t buf[sizeof(header)];
134+
} ota_header;
135+
uint32_t crc32, bytes_read;
136+
uint8_t crc_buf[128];
137+
138+
/* Read the OTA header ... */
139+
update_file.read(ota_header.buf, sizeof(ota_header.buf));
140+
141+
/* ... and check first length ... */
142+
if (ota_header.header.len != (update_file.size() - sizeof(ota_header.buf))) {
143+
update_file.close();
144+
update_file.erase();
145+
goto boot;
146+
}
147+
/* ... and the CRC second ... initialize CRC ... */
148+
crc32 = 0xFFFFFFFF;
149+
/* ... and calculate over file ... */
150+
for(bytes_read = 0;
151+
bytes_read < (ota_header.header.len - sizeof(crc_buf));
152+
bytes_read += sizeof(crc_buf))
153+
{
154+
update_file.read(crc_buf, sizeof(crc_buf));
155+
crc32 = crc_update(crc32, crc_buf, sizeof(crc_buf));
156+
}
157+
update_file.read(crc_buf, ota_header.header.len - bytes_read);
158+
crc32 = crc_update(crc32, crc_buf, ota_header.header.len - bytes_read);
159+
/* ... then finalise ... */
160+
crc32 ^= 0xFFFFFFFF;
161+
/* ... and compare. */
162+
if (ota_header.header.crc32 != crc32) {
163+
update_file.close();
164+
update_file.erase();
165+
goto boot;
166+
}
167+
168+
/* Rewind to start of LZSS compressed binary. */
169+
update_file.seek(sizeof(ota_header.buf));
170+
76171
/* Erase the complete flash starting from the SSU forward
77172
* because we've got no possibility of knowing how large
78173
* the decompressed binary will finally be.

0 commit comments

Comments
 (0)