static private ChecksumResult CalculateLayer2Checksum(string filename, int OffsetLayer2, bool autocorrect, ChecksumDelegate.ChecksumUpdate delegateShouldUpdate) { ChecksumResult result = ChecksumResult.Layer2Failed; uint checksum0 = 0; uint checksum1 = 0; uint sum0 = 0; uint matrix_dimension = 0; uint partial_address = 0; uint x = 0; /* * Get 0x100 byte buffer from CHPTR – CHPTR + 0xFF * Because level 1 is in that area level1 must be correct first * Prepare coded_buffer (0x100 buffer from chptr) with loop: coded_buffer(x) = (buffer (x) + 0xD6) xor 0x21 * (add 0xd6 to every byte of buffer, then xor it by 0x21) * [ 1 indexed, not 0 indexed ] * So, 0x101 byte buffer with first byte ignored (convention) * */ byte[] coded_buffer = FileTools.readdatafromfile(filename, OffsetLayer2, 0x100); for (int i = 0; i < coded_buffer.Length; i++) { byte b = coded_buffer[i]; b += 0xD6; b ^= 0x21; coded_buffer[i] = b; } byte[] complete_file = FileTools.readdatafromfile(filename, 0, 0x100000); int index = 0; bool chk_found = false; while (index < 0x100 && !chk_found) { if ((coded_buffer[index] == 0xFB) && (coded_buffer[index + 6] == 0xFC) && (coded_buffer[index + 0x0C] == 0xFD)) { sum0 = ((uint)coded_buffer[index + 1] * 0x01000000 + (uint)coded_buffer[index + 2] * 0x010000 + (uint)coded_buffer[index + 3] * 0x100 + (uint)coded_buffer[index + 4]); matrix_dimension = (uint)coded_buffer[index + 7] * 0x01000000 + (uint)coded_buffer[index + 8] * 0x010000 + (uint)coded_buffer[index + 9] * 0x100 + (uint)coded_buffer[index + 10]; partial_address = (uint)coded_buffer[index + 0x0d] * 0x01000000 + (uint)coded_buffer[index + 0x0e] * 0x010000 + (uint)coded_buffer[index + 0x0F] * 0x100 + (uint)coded_buffer[index + 0x10]; if (matrix_dimension >= 0x020000) { checksum0 = 0; x = partial_address; while (x < (matrix_dimension - 4)) { checksum0 = checksum0 + (uint)complete_file[x]; x++; } checksum0 = checksum0 + (uint)complete_file[matrix_dimension - 1]; checksum1 = 0; x = partial_address; while (x < (matrix_dimension - 4)) { checksum1 = checksum1 + (uint)complete_file[x] * 0x01000000 + (uint)complete_file[x + 1] * 0x10000 + (uint)complete_file[x + 2] * 0x100 + (uint)complete_file[x + 3]; x = x + 4; } if ((checksum0 & 0xFFF00000) != (sum0 & 0xFFF00000)) { checksum0 = checksum1; } if (checksum0 != sum0) { logger.Debug("Layer 2 checksum was invalid, should be updated!"); if (autocorrect) { result = UpdateLayer2(filename, OffsetLayer2, checksum0, index); } else { string filechecksum = sum0.ToString("X8"); string realchecksum = checksum0.ToString("X8"); if (delegateShouldUpdate("Checksum validation Layer 2", filechecksum, realchecksum)) { result = UpdateLayer2(filename, OffsetLayer2, checksum0, index); } else { result = ChecksumResult.Layer2Failed; } } } else { result = ChecksumResult.Ok; } chk_found = true; } } index++; } if (!chk_found) { logger.Debug("Layer 2 checksum could not be calculated [ file incompatible ]"); } return(result); }
static public ChecksumResult VerifyChecksum(string filename, bool autocorrect, bool autofixFooter, ChecksumDelegate.ChecksumUpdate delegateShouldUpdate) { csumArea = new csum_area_t[16]; for (int i = 0; i < csumArea.Length; i++) { csumArea[i] = new csum_area_t(); } ChecksumResult result = ChecksumResult.Ok; T7FileHeader t7InfoHeader = new T7FileHeader(); t7InfoHeader.init(filename, autofixFooter); int sramOffset = t7InfoHeader.getSramOffset(); int fwLength = t7InfoHeader.getFWLength(); int calculatedFWChecksum = calculateFWChecksum(filename, sramOffset); uint calculatedF2Checksum = calculateF2Checksum(filename, 0, fwLength); int calculatedFBChecksum = calculateFBChecksum(filename, 0, fwLength); int readF2checksum = t7InfoHeader.getChecksumF2(); int readFBchecksum = t7InfoHeader.getChecksumFB(); if (readF2checksum != 0) { if (t7InfoHeader.getChecksumF2() != (int)calculatedF2Checksum) { result = ChecksumResult.ChecksumF2Failed; } } if (t7InfoHeader.getChecksumFB() != calculatedFBChecksum) { result = ChecksumResult.ChecksumFBFailed; } if (getFWChecksum(filename, sramOffset) != calculatedFWChecksum) { result = ChecksumResult.ChecksumFWFailed; } if (result != ChecksumResult.Ok) { logger.Debug("Checksum was invalid, should be updated!"); logger.Debug("calculatedF2Checksum = " + calculatedF2Checksum.ToString("X8") + " readF2checksum = " + readF2checksum.ToString("X8")); logger.Debug("calculatedFBChecksum = " + calculatedFBChecksum.ToString("X8") + " readFBchecksum = " + readFBchecksum.ToString("X8")); logger.Debug("calculatedFWChecksum = " + calculatedFWChecksum.ToString("X8") + " getFWChecksum = " + getFWChecksum(filename, sramOffset).ToString("X8")); if (autocorrect) { result = updateChecksum(filename, t7InfoHeader, calculatedFWChecksum, calculatedF2Checksum, calculatedFBChecksum, sramOffset); } else { if (delegateShouldUpdate(null, null, null)) { result = updateChecksum(filename, t7InfoHeader, calculatedFWChecksum, calculatedF2Checksum, calculatedFBChecksum, sramOffset); } } } return(result); }
public static ChecksumResult VerifyChecksum(string filename, bool autocorrect, ChecksumDelegate.ChecksumUpdate delegateShouldUpdate) { int checksumAreaOffset = GetChecksumAreaOffset(filename); if (checksumAreaOffset > FileT8.Length) { return(ChecksumResult.InvalidFileLength); } logger.Debug("Checksum area offset: " + checksumAreaOffset.ToString("X8")); byte[] hash = CalculateLayer1ChecksumMD5(filename, checksumAreaOffset); // compare hash to bytes after checksum areaoffset byte[] layer1checksuminfile = FileTools.readdatafromfile(filename, checksumAreaOffset + 2, 16); if (!CompareByteArray(hash, layer1checksuminfile)) { if (autocorrect) { if (!FileTools.savedatatobinary(checksumAreaOffset + 2, 16, hash, filename)) { return(ChecksumResult.UpdateFailed); } } else { string filechecksum = string.Empty; string realchecksum = string.Empty; for (int i = 0; i < layer1checksuminfile.Length; i++) { filechecksum += layer1checksuminfile[i].ToString("X2") + " "; realchecksum += hash[i].ToString("X2") + " "; } if (delegateShouldUpdate("Checksum validation Layer 1", filechecksum, realchecksum)) { if (!FileTools.savedatatobinary(checksumAreaOffset + 2, 16, hash, filename)) { return(ChecksumResult.UpdateFailed); } } else { return(ChecksumResult.Layer1Failed); } } } return(CalculateLayer2Checksum(filename, checksumAreaOffset, autocorrect, delegateShouldUpdate)); }
/// <summary> /// Validates a binary before flashing. /// </summary> /// <param name="filename">filename to flash</param> /// <returns>ChecksumResult.Ok if checksum is correct</returns> public static ChecksumResult VerifyChecksum(string filename, bool autocorrect, ChecksumDelegate.ChecksumUpdate delegateShouldUpdate) { FileInfo fi = new FileInfo(filename); long len = fi.Length; uint End; uint Checksum; // Verify file length. if (len != FileT5.LengthT52 && len != FileT5.LengthT55) { return(ChecksumResult.InvalidFileLength); } // Store file in a local buffer. byte[] Bufr = FileTools.readdatafromfile(filename, 0, (int)len); // No need for further checks if result is ok. if (ChecksumMatch(Bufr, (uint)len, out End, out Checksum) == true) { return(ChecksumResult.Ok); } // Can't do anything if footer is broken. else if (End == 0) { return(ChecksumResult.Invalid); } uint StoredChecksum = (uint)( Bufr[len - 4] << 24 | Bufr[len - 3] << 16 | Bufr[len - 2] << 8 | Bufr[len - 1]); if (autocorrect == true) { Writefile(filename, Checksum, (uint)len); return(ChecksumResult.Ok); } else { string CalculatedSum = Checksum.ToString("X"); string ActualSum = StoredChecksum.ToString("X"); if (delegateShouldUpdate(null, ActualSum, CalculatedSum)) { Writefile(filename, Checksum, (uint)len); return(ChecksumResult.Ok); } } return(ChecksumResult.Invalid); }