Mercurial > public > ostc_companion
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 } |
