30 lines
1.6 KiB
Python
30 lines
1.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate synthetic Heltec-V3 KISS/RSA test data; never access a serial port."""
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
from cryptography.hazmat.primitives import hashes, serialization
|
|
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
|
from archy_rns_identity import rns_private_blob, lxmf_destination_hash
|
|
|
|
key = rsa.generate_private_key(public_exponent=65537, key_size=1024)
|
|
private = key.private_bytes(serialization.Encoding.DER, serialization.PrivateFormat.PKCS8, serialization.NoEncryption())
|
|
eeprom = bytearray(296)
|
|
eeprom[:11] = bytes([0xC1,0xCA,1,0,0,0,7,0,0,0,1])
|
|
checksum = hashlib.md5(eeprom[:11]).digest()
|
|
eeprom[11:27] = checksum
|
|
eeprom[27:155] = key.sign(checksum,padding.PSS(mgf=padding.MGF1(hashes.SHA256()),salt_length=padding.PSS.MAX_LENGTH),hashes.SHA256())
|
|
eeprom[155] = 0x73
|
|
def frame(command,data):
|
|
data = bytes(data).replace(b'\xdb',b'\xdb\xdd').replace(b'\xc0',b'\xdb\xdc')
|
|
return b'\xc0'+bytes([command])+data+b'\xc0'
|
|
def stream(rom):
|
|
return b''.join((frame(0x08,[0x46]),frame(0x50,[1,86]),frame(0x48,[0x80]),frame(0x49,[0x81]),
|
|
frame(0x47,[0x3b]),frame(0x60,b'\x01'+b'a'*32),frame(0x60,b'\x02'+b'a'*32),frame(0x51,rom)))
|
|
corrupt = bytearray(eeprom); corrupt[28] ^= 1
|
|
Path(sys.argv[1]).parent.mkdir(parents=True, exist_ok=True)
|
|
Path(sys.argv[1]).write_text(json.dumps({'keys':{'firmware/signing.key':private.hex(),
|
|
'firmware/device.key':(b'x'*32+b'y'*32).hex()}, 'valid':stream(eeprom).hex(), 'corrupt':stream(corrupt).hex(),
|
|
'radio_identity':rns_private_blob(bytes(range(32))).hex(), 'destination':lxmf_destination_hash(bytes(range(32))).hex()}))
|