Skip to content
BMW DME / Part X / 21 Checksum Algorithms & Security Access Maste…
Source
DOC 37 § 21
Contents
Siemens MS42 / MS43 16-Bit CRC-CCITT Implementation and 3 more
Systems covered
`MS42`, `MS43`, `MSD80`
Size
0 tables · 3 code/diagrams · ~498 words

Siemens MS42 / MS43 16-Bit CRC-CCITT Implementation

Below are verified mathematical formulas and executable reference implementations for each generation:

21.1 Siemens MS42 / MS43 16-Bit CRC-CCITT Implementation#

The MS42 and MS43 calculate three 16-bit CRC checksums across the bootloader, program code, and calibration blocks using the standard CRC-CCITT polynomial:

  • Polynomial: x^{16} + x^{12} + x^5 + 1 (0x1021)
  • Initialization Value: 0xFFFF
  • Bit Order: Most Significant Bit (MSB) first (no reflection).
def calculate_ms4x_crc16(  
    data: bytes, start_offset: int, end_offset: int  
) -> int:  
  # Siemens MS42 / MS43 16-bit CCITT checksum  
  # Memory boundaries:  
  #   - MS43 Calibration: start=0x70000, end=0x73FDF, stored at 0x73FE0  
  #   - MS43 Program: start=0x10000, end=0x6FDDF, stored at 0x6FDE0  
  crc = 0xFFFF  
  for i in range(start_offset, end_offset + 1):  
    byte = data[i]  
    crc ^= byte << 8  
    for _ in range(8):  
      if crc & 0x8000:  
        crc = ((crc << 1) ^ 0x1021) & 0xFFFF  
      else:  
        crc = (crc << 1) & 0xFFFF  
  return crc  

21.2 Siemens MS43 32-Bit Addition Monitor Checksum#

Before evaluating CRC16, the MS43 monitors calibration memory integrity via a 32-bit DWORD additive accumulation located at 0x72FFC:

def calculate_ms43_32bit_addition(data: bytes, start: int, end: int) -> int:  
  # 32-bit addition checksum for MS43 calibration block  
  # Boundary: 0x70000 to 0x72FFB, stored at 0x72FFC as Big-Endian DWORD  
  total_sum = 0  
  for i in range(start, end + 1, 4):  
    dword = int.from_bytes(data[i : i + 4], byteorder="big")  
    total_sum = (total_sum + dword) & 0xFFFFFFFF  
  return total_sum  

21.3 Siemens MS45 Standard Ethernet CRC32 Implementation#

The MS45 monitors its calibration sector (0x40200 to 0x5CFFF) using a 32-bit CRC stored at 0x40100:

  • Polynomial: 0x04C11DB7
  • Initial Value: 0xFFFFFFFF
  • XOR Output: 0x00000000
def calculate_ms45_crc32(  
    data: bytes, start: int = 0x40200, end: int = 0x5CFFF  
) -> int:  
  # Ethernet CRC32 for Siemens MS45  
  crc = 0xFFFFFFFF  
  poly = 0x04C11DB7  
  for i in range(start, end + 1):  
    byte = data[i]  
    crc ^= (byte << 24) & 0xFFFFFFFF  
    for _ in range(8):  
      if crc & 0x80000000:  
        crc = ((crc << 1) ^ poly) & 0xFFFFFFFF  
      else:  
        crc = (crc << 1) & 0xFFFFFFFF  
  return crc  

21.4 Cryptographic RSA-1024 Signature Structure (MS45 & MSD80)#

The bootloader validates flash signatures using the RSA asymmetric public-key cryptosystem:

  • Mathematical Principle: Given public modulus n (1024 ext{ bits} = 128 ext{ bytes}) and public exponent e (typically 65537 = 0x10001), the signature s stored at 0x40170 is verified against the SHA-1 digest H of the calibration image: m = s^e \pmod n
  • The decrypted block m must match the standard PKCS#1 v1.5 padding string: ext{Padding: } 0x00 \quad 0x01 \quad [0xFF imes 105 ext{ bytes}] \quad 0x00 \quad [ ext{20-Byte SHA-1 Digest}]
  • Because factory private signing keys are strictly protected within BMW engineering servers, OBD flashing tools (MS45 Flasher) patch the bootloader instruction verification sequence or use specialized development keys to recalculate valid RSA signature envelopes.