#!/usr/bin/env python3
# UNECE R156 SUMS: software update package verification
import hashlib, hmac, struct
def verify_update_package(package_bytes: bytes, expected_sha256: str,
ecdsa_signature: bytes, oem_public_key) -> dict:
"""
SUMS verification chain per UNECE R156:
1. Verify SHA-256 hash integrity
2. Verify ECDSA-P256 signature authenticity
3. Check update version monotonicity (anti-rollback)
"""
# Step 1: Integrity check
actual_hash = hashlib.sha256(package_bytes).hexdigest()
integrity_ok = actual_hash == expected_sha256
# Step 2: Authenticity check (ECDSA-P256 signature over SHA-256 hash)
# Using cryptography library (python-cryptography)
try:
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
oem_public_key.verify(ecdsa_signature,
package_bytes,
ec.ECDSA(hashes.SHA256()))
authenticity_ok = True
except Exception:
authenticity_ok = False
# Step 3: Extract and check version from package header
# Package header: magic(4) + version(4) + ...
magic = struct.unpack(">I", package_bytes[:4])[0]
new_version = struct.unpack(">I", package_bytes[4:8])[0]
current_version = get_ecu_current_version() # from ECU NVM
rollback_ok = new_version >= current_version
return {
"integrity": integrity_ok,
"authenticity": authenticity_ok,
"anti_rollback": rollback_ok,
"install": integrity_ok and authenticity_ok and rollback_ok,
}
def get_ecu_current_version(): return 0x0302 # placeholder