comparison HexFile.cpp @ 8:21ce6187d32e

Minor changes done by automatic style checker
author Ideenmodellierer
date Mon, 12 Jan 2026 13:51:17 +0000
parents 0b3630a29ad8
children
comparison
equal deleted inserted replaced
7:0969ef86c42d 8:21ce6187d32e
51 #include "AES/rijndael.h" 51 #include "AES/rijndael.h"
52 52
53 /////////////////////////////////////////////////////////////////////////////// 53 ///////////////////////////////////////////////////////////////////////////////
54 54
55 HexFile::HexFile() 55 HexFile::HexFile()
56 : _memSize(0), 56 : _memSize(0)
57 ,
57 #ifdef FROG_MASTER 58 #ifdef FROG_MASTER
58 _baseAddress(0), 59 _baseAddress(0)
60 ,
59 #endif 61 #endif
60 _buffer(0) 62 _buffer(0)
61 {} 63 {}
62 64
63 HexFile::~HexFile() 65 HexFile::~HexFile()
64 { 66 {
65 delete[] _buffer; _buffer = 0; 67 delete[] _buffer;
68 _buffer = 0;
66 } 69 }
67 70
68 /////////////////////////////////////////////////////////////////////////////// 71 ///////////////////////////////////////////////////////////////////////////////
69 72
70 bool HexFile::allocate(size_t memSize, unsigned char fill) 73 bool HexFile::allocate(size_t memSize, unsigned char fill)
77 return true; 80 return true;
78 } 81 }
79 82
80 bool HexFile::sqwiz(size_t newMemSize) 83 bool HexFile::sqwiz(size_t newMemSize)
81 { 84 {
82 if( newMemSize >= _memSize ) { 85 if (newMemSize >= _memSize) {
83 LOG_THROW( "Squiz failed" ); 86 LOG_THROW("Squiz failed");
84 } 87 }
85 _memSize = newMemSize; 88 _memSize = newMemSize;
86 return true; 89 return true;
87 } 90 }
88 91
91 static size_t bytes = 0; 94 static size_t bytes = 0;
92 95
93 void HexFile::readLine() 96 void HexFile::readLine()
94 { 97 {
95 QByteArray line = _file.readLine(); 98 QByteArray line = _file.readLine();
96 if( line[0] != ':' ) 99 if (line[0] != ':')
97 LOG_THROW( "Bad HEX format" ); 100 LOG_THROW("Bad HEX format");
98 101
99 unsigned char checksum = 0; 102 unsigned char checksum = 0;
100 bool ok = true; 103 bool ok = true;
101 for(int i=1; ok && i<line.length(); i+=2) { 104 for (int i = 1; ok && i < line.length(); i += 2) {
102 if( line[i]=='\r' || line[i]=='\n' ) 105 if (line[i] == '\r' || line[i] == '\n')
103 break; 106 break;
104 checksum += line.mid(i,2).toInt(&ok,16); 107 checksum += line.mid(i, 2).toInt(&ok, 16);
105 } 108 }
106 if( ! ok ) 109 if (!ok)
107 LOG_THROW( "Bad HEX header" ); 110 LOG_THROW("Bad HEX header");
108 if( checksum != 0 ) 111 if (checksum != 0)
109 LOG_THROW( "Bad HEX checksum" ); 112 LOG_THROW("Bad HEX checksum");
110 113
111 int len = line.mid(1,2).toInt(0, 16); 114 int len = line.mid(1, 2).toInt(0, 16);
112 int addr = line.mid(3,2).toInt(0, 16) << 8 115 int addr = line.mid(3, 2).toInt(0, 16) << 8 | line.mid(5, 2).toInt(0, 16);
113 | line.mid(5,2).toInt(0, 16); 116 int type = line.mid(7, 2).toInt(0, 16);
114 int type = line.mid(7,2).toInt(0, 16); 117
115 118 switch (type) {
116 switch( type )
117 {
118 case 00: //---- Data record ---------------------------------------------- 119 case 00: //---- Data record ----------------------------------------------
119 if( _baseAddress == 0x300000 ) // Skip configuration bits. 120 if (_baseAddress == 0x300000) // Skip configuration bits.
120 return; 121 return;
121 if( _baseAddress == 0xF00000 ) // Skip internal prom reset. 122 if (_baseAddress == 0xF00000) // Skip internal prom reset.
122 return; 123 return;
123 124
124 for(int i=0; i<len; i++, ++addr) 125 for (int i = 0; i < len; i++, ++addr) {
125 {
126 size_t a = _baseAddress + addr; 126 size_t a = _baseAddress + addr;
127 if( a >= _memSize ) 127 if (a >= _memSize)
128 LOG_THROW( "BAD HEX address" ); 128 LOG_THROW("BAD HEX address");
129 129
130 if( _buffer[a] != 0xFF ) 130 if (_buffer[a] != 0xFF)
131 LOG_THROW( "Double write" ); 131 LOG_THROW("Double write");
132 132
133 _buffer[a] = line.mid(9+i*2,2).toInt(&ok,16); 133 _buffer[a] = line.mid(9 + i * 2, 2).toInt(&ok, 16);
134 if( !ok ) 134 if (!ok)
135 LOG_THROW( "Bad HEX byte" ); 135 LOG_THROW("Bad HEX byte");
136 bytes++; 136 bytes++;
137 } 137 }
138 break; 138 break;
139 139
140 case 01: //---- END OF FILE record --------------------------------------- 140 case 01: //---- END OF FILE record ---------------------------------------
141 _file.seek(-1); // Force to end of file. 141 _file.seek(-1); // Force to end of file.
142 break; 142 break;
143 143
144 case 02: //---- Segment address record ----------------------------------- 144 case 02: //---- Segment address record -----------------------------------
145 if( len != 2 || addr != 0 ) 145 if (len != 2 || addr != 0)
146 LOG_THROW( "Bad HEX Segment Address record" ); 146 LOG_THROW("Bad HEX Segment Address record");
147 _baseAddress = line.mid(9,4).toInt(0,16) << 4; 147 _baseAddress = line.mid(9, 4).toInt(0, 16) << 4;
148 break; 148 break;
149 149
150 case 04: //---- Extended Linear Address Record --------------------------- 150 case 04: //---- Extended Linear Address Record ---------------------------
151 if( len != 2 || addr != 0 ) 151 if (len != 2 || addr != 0)
152 LOG_THROW( "Bad HEX Extended Linear Address Record" ); 152 LOG_THROW("Bad HEX Extended Linear Address Record");
153 _baseAddress = line.mid( 9,2).toInt(0,16) << 20 153 _baseAddress = line.mid(9, 2).toInt(0, 16) << 20 | line.mid(11, 2).toInt(0, 16) << 16;
154 | line.mid(11,2).toInt(0,16) << 16;
155 break; 154 break;
156 155
157 default: 156 default:
158 LOG_THROW("Bad HEX subtype"); 157 LOG_THROW("Bad HEX subtype");
159 } 158 }
160 } 159 }
161 160
162 /////////////////////////////////////////////////////////////////////////////// 161 ///////////////////////////////////////////////////////////////////////////////
163 162
164 void HexFile::load(const QString& fileName) 163 void HexFile::load(const QString &fileName)
165 { 164 {
166 Q_ASSERT(_buffer); 165 Q_ASSERT(_buffer);
167 166
168 _file.setFileName(fileName); 167 _file.setFileName(fileName);
169 if( ! _file.open(QIODevice::ReadOnly) ) 168 if (!_file.open(QIODevice::ReadOnly))
170 LOG_THROW("Can't open HEX file"); 169 LOG_THROW("Can't open HEX file");
171 170
172 bytes = 0; 171 bytes = 0;
173 while( ! _file.atEnd() ) 172 while (!_file.atEnd()) {
174 {
175 PROGRESS(_file.pos(), _file.size()); 173 PROGRESS(_file.pos(), _file.size());
176 readLine(); 174 readLine();
177 } 175 }
178 PROGRESS_RESET(); 176 PROGRESS_RESET();
179 177
180 _file.close(); 178 _file.close();
181 179
182 LOG_TRACE( int(bytes/1024.0f) << "KB loaded (" 180 LOG_TRACE(int(bytes / 1024.0f)
183 << int(bytes * 100.0f / _memSize) << "% of firmware area)."); 181 << "KB loaded (" << int(bytes * 100.0f / _memSize) << "% of firmware area).");
184 } 182 }
185 183
186 /////////////////////////////////////////////////////////////////////////////// 184 ///////////////////////////////////////////////////////////////////////////////
187 185
188 const unsigned char* HexFile::data() const 186 const unsigned char *HexFile::data() const
189 { 187 {
190 Q_ASSERT(_buffer); 188 Q_ASSERT(_buffer);
191 return _buffer; 189 return _buffer;
192 } 190 }
193 191
197 { 195 {
198 Q_ASSERT(_buffer); 196 Q_ASSERT(_buffer);
199 197
200 unsigned short low = 0; 198 unsigned short low = 0;
201 unsigned short high = 0; 199 unsigned short high = 0;
202 for(size_t i=0; i < _memSize; ++i) 200 for (size_t i = 0; i < _memSize; ++i) {
203 { 201 low += _buffer[i];
204 low += _buffer[i];
205 high += low; 202 high += low;
206 } 203 }
207 return (((unsigned int)high) << 16) + low; 204 return (((unsigned int) high) << 16) + low;
208 } 205 }
209 206
210 /////////////////////////////////////////////////////////////////////////////// 207 ///////////////////////////////////////////////////////////////////////////////
211 208
212 #ifndef FROG_MASTER 209 #ifndef FROG_MASTER
213 void HexFile::saveEncrypted(const QString&, byte [16]) 210 void HexFile::saveEncrypted(const QString &, byte[16])
214 { 211 {
215 LOG_THROW( "No encryption" ); 212 LOG_THROW("No encryption");
216 } 213 }
217 #else 214 #else
218 void HexFile::saveEncrypted(const QString& fileName, byte secretKey[16]) 215 void HexFile::saveEncrypted(const QString &fileName, byte secretKey[16])
219 { 216 {
220 _file.setFileName(fileName); 217 _file.setFileName(fileName);
221 if( ! _file.open(QIODevice::WriteOnly|QIODevice::Truncate) ) 218 if (!_file.open(QIODevice::WriteOnly | QIODevice::Truncate))
222 LOG_THROW( "Can't save to encrypted file" ); 219 LOG_THROW("Can't save to encrypted file");
223 220
224 QTextStream out(&_file); 221 QTextStream out(&_file);
225 out.setIntegerBase(16); 222 out.setIntegerBase(16);
226 out.setPadChar('0'); 223 out.setPadChar('0');
227 224
228 //---- Generates 128 bits of random initialization vector ---------------- 225 //---- Generates 128 bits of random initialization vector ----------------
229 Rijndael::CFB<128>::IV iv = {0}; 226 Rijndael::CFB<128>::IV iv = {0};
230 Rijndael::ECB<128> PRNG; PRNG.setupEncrypt(secretKey); 227 Rijndael::ECB<128> PRNG;
231 for(int i=0; i<sizeof iv; ++i) 228 PRNG.setupEncrypt(secretKey);
229 for (int i = 0; i < sizeof iv; ++i)
232 iv[i] = PRNG.get_random() % 256; 230 iv[i] = PRNG.get_random() % 256;
233 231
234 size_t bytes = 0; // encrypted fake address 232 size_t bytes = 0; // encrypted fake address
235 for(int i0 = 0; i0 < sizeof iv; i0+=0x10) 233 for (int i0 = 0; i0 < sizeof iv; i0 += 0x10) {
236 { 234 out << qSetFieldWidth(1) << ":" << qSetFieldWidth(6) << bytes << qSetFieldWidth(2);
237 out << qSetFieldWidth(1) << ":" 235 for (int i = 0; i < 0x10; i++)
238 << qSetFieldWidth(6) << bytes 236 out << iv[i0 + i];
239 << qSetFieldWidth(2);
240 for(int i=0; i<0x10; i++)
241 out << iv[i0+i];
242 out << qSetFieldWidth(1) << "\n"; 237 out << qSetFieldWidth(1) << "\n";
243 bytes += 0x10; 238 bytes += 0x10;
244 } 239 }
245 240
246 //---- Create stream encryptor ------------------------------------------- 241 //---- Create stream encryptor -------------------------------------------
248 243
249 //---- Process data ------------------------------------------------------ 244 //---- Process data ------------------------------------------------------
250 PROGRESS(0, _memSize); 245 PROGRESS(0, _memSize);
251 246
252 byte encrypted[32]; 247 byte encrypted[32];
253 for(size_t addr = 0; addr < _memSize; addr += 0x10) 248 for (size_t addr = 0; addr < _memSize; addr += 0x10) {
254 {
255 PROGRESS(addr, _memSize); 249 PROGRESS(addr, _memSize);
256 250
257 enc.encrypt(_buffer + addr, encrypted); 251 enc.encrypt(_buffer + addr, encrypted);
258 out << qSetFieldWidth(1) << ":" 252 out << qSetFieldWidth(1) << ":" << qSetFieldWidth(6) << bytes << qSetFieldWidth(2);
259 << qSetFieldWidth(6) << bytes 253 for (int i = 0; i < 16; i++)
260 << qSetFieldWidth(2);
261 for(int i=0; i<16; i++)
262 out << encrypted[i]; 254 out << encrypted[i];
263 out << qSetFieldWidth(1) << "\n"; 255 out << qSetFieldWidth(1) << "\n";
264 bytes += 16; 256 bytes += 16;
265 } 257 }
266 258
267 //---- Process data ------------------------------------------------------ 259 //---- Process data ------------------------------------------------------
268 unsigned int sum = checksum(); // 33.29.BD.1D 260 unsigned int sum = checksum(); // 33.29.BD.1D
269 out << qSetFieldWidth(1) << ":" 261 out << qSetFieldWidth(1) << ":" << qSetFieldWidth(6) << bytes << qSetFieldWidth(2)
270 << qSetFieldWidth(6) << bytes 262 << ((sum) & 0xff) << ((sum >> 8) & 0xff) << ((sum >> 16) & 0xff) << ((sum >> 24) & 0xff)
271 << qSetFieldWidth(2) 263 << qSetFieldWidth(1) << "\n";
272 << ((sum ) & 0xff) 264
273 << ((sum>> 8) & 0xff) 265 qDebug().nospace() << int(bytes / 1024.0f) << "KB saved into " << fileName.section('/', -1);
274 << ((sum>>16) & 0xff)
275 << ((sum>>24) & 0xff)
276 << qSetFieldWidth(1) << "\n"
277 ;
278
279 qDebug().nospace() << int( bytes/1024.0f) << "KB saved into "
280 << fileName.section('/', -1);
281 266
282 PROGRESS_RESET(); 267 PROGRESS_RESET();
283 } 268 }
284 #endif 269 #endif
285 270
286 /////////////////////////////////////////////////////////////////////////////// 271 ///////////////////////////////////////////////////////////////////////////////
287 272
288 void HexFile::loadEncrypted(const QString& fileName, unsigned char secretKey[16]) 273 void HexFile::loadEncrypted(const QString &fileName, unsigned char secretKey[16])
289 { 274 {
290 Q_ASSERT(_buffer); 275 Q_ASSERT(_buffer);
291 276
292 _file.setFileName(fileName); 277 _file.setFileName(fileName);
293 if( ! _file.open(QIODevice::ReadOnly) ) 278 if (!_file.open(QIODevice::ReadOnly))
294 LOG_THROW( "Cannot open HEX file " << fileName ); 279 LOG_THROW("Cannot open HEX file " << fileName);
295 280
296 //---- Read 128 bits of initialization vector ---------------------------- 281 //---- Read 128 bits of initialization vector ----------------------------
297 Rijndael::CFB<128>::IV iv = {0}; 282 Rijndael::CFB<128>::IV iv = {0};
298 283
299 unsigned int bytes = 0; 284 unsigned int bytes = 0;
300 bool ok = true; 285 bool ok = true;
301 for(size_t i0 = 0; i0 < sizeof iv; i0+=0x10) 286 for (size_t i0 = 0; i0 < sizeof iv; i0 += 0x10) {
302 {
303 QByteArray line = _file.readLine(); 287 QByteArray line = _file.readLine();
304 if( line[0] != ':' ) 288 if (line[0] != ':')
305 LOG_THROW( "Bad HEX line" ); 289 LOG_THROW("Bad HEX line");
306 290
307 unsigned int readAddr = line.mid(1,6).toInt(&ok, 16); 291 unsigned int readAddr = line.mid(1, 6).toInt(&ok, 16);
308 if( !ok || readAddr != bytes ) 292 if (!ok || readAddr != bytes)
309 LOG_THROW( "Bad HEX address" ); 293 LOG_THROW("Bad HEX address");
310 294
311 for(int i=0; i<0x10; i++) 295 for (int i = 0; i < 0x10; i++)
312 iv[i0+i] = line.mid(2*i+7,2).toInt(&ok, 16); 296 iv[i0 + i] = line.mid(2 * i + 7, 2).toInt(&ok, 16);
313 if( !ok ) 297 if (!ok)
314 LOG_THROW( "Bad HEX file format" ); 298 LOG_THROW("Bad HEX file format");
315 299
316 bytes += 0x10; 300 bytes += 0x10;
317 } 301 }
318 302
319 //---- Create stream decryptor ------------------------------------------- 303 //---- Create stream decryptor -------------------------------------------
320 Rijndael::CFB<128> dec(secretKey, iv); 304 Rijndael::CFB<128> dec(secretKey, iv);
321 305
322 //---- Process data ------------------------------------------------------ 306 //---- Process data ------------------------------------------------------
323 PROGRESS(0, (int)_memSize); 307 PROGRESS(0, (int) _memSize);
324 308
325 Rijndael::Block encrypted; 309 Rijndael::Block encrypted;
326 for(size_t addr = 0; addr < _memSize; addr += 0x10) 310 for (size_t addr = 0; addr < _memSize; addr += 0x10) {
327 { 311 PROGRESS((int) addr, (int) _memSize);
328 PROGRESS((int)addr, (int)_memSize);
329 312
330 QByteArray line = _file.readLine(); 313 QByteArray line = _file.readLine();
331 if( line[0] != ':' ) 314 if (line[0] != ':')
332 LOG_THROW( "Bad HEX line" ); 315 LOG_THROW("Bad HEX line");
333 316
334 unsigned int readAddr = line.mid(1,6).toInt(&ok, 16); 317 unsigned int readAddr = line.mid(1, 6).toInt(&ok, 16);
335 if( !ok || readAddr != bytes ) 318 if (!ok || readAddr != bytes)
336 LOG_THROW( "Bad HEX address" ); 319 LOG_THROW("Bad HEX address");
337 320
338 for(int i=0; i<0x10; i++) 321 for (int i = 0; i < 0x10; i++)
339 encrypted[i] = line.mid(2*i+7,2).toInt(&ok, 16); 322 encrypted[i] = line.mid(2 * i + 7, 2).toInt(&ok, 16);
340 if( !ok ) 323 if (!ok)
341 LOG_THROW( "Bad HEX file format" ); 324 LOG_THROW("Bad HEX file format");
342 bytes += 0x10; 325 bytes += 0x10;
343 326
344 dec.decrypt(encrypted, *(Rijndael::Block*)(_buffer+addr)); 327 dec.decrypt(encrypted, *(Rijndael::Block *) (_buffer + addr));
345 } 328 }
346 QByteArray line = _file.readLine(); 329 QByteArray line = _file.readLine();
347 if( bytes != (unsigned int)line.mid(1,6).toInt(&ok, 16) || !ok ) 330 if (bytes != (unsigned int) line.mid(1, 6).toInt(&ok, 16) || !ok)
348 LOG_THROW( "Bad HEX address" ); 331 LOG_THROW("Bad HEX address");
349 332
350 unsigned int sum = line.mid( 7,2).toInt(&ok, 16) 333 unsigned int sum = line.mid(7, 2).toInt(&ok, 16) + (line.mid(9, 2).toInt(&ok, 16) << 8)
351 + (line.mid( 9,2).toInt(&ok, 16) << 8 ) 334 + (line.mid(11, 2).toInt(&ok, 16) << 16)
352 + (line.mid(11,2).toInt(&ok, 16) << 16) 335 + (line.mid(13, 2).toInt(&ok, 16) << 24);
353 + (line.mid(13,2).toInt(&ok, 16) << 24); 336 if (sum != checksum())
354 if( sum != checksum() ) 337 LOG_THROW("Bad HEX checksum");
355 LOG_THROW( "Bad HEX checksum" );
356 338
357 PROGRESS_RESET(); 339 PROGRESS_RESET();
358 } 340 }