Files
eculocate/otaclient.py
T
2026-01-23 23:57:45 +00:00

82 lines
1.9 KiB
Python

import socket
import struct
import sys
import nacl
import os
import nacl.hash
from nacl.signing import SigningKey
from nacl.encoding import RawEncoder
HASHER = nacl.hash.sha256
BLOCK_SIZE=4096
with open("privkey.bin", "rb") as f:
signing_key = SigningKey(f.read(), encoder=RawEncoder)
PEER=("eculocate.local", 5000)
# PEER=("localhost",5000)
sock = socket.create_connection(PEER)
with open(sys.argv[1], "rb") as f:
rom_image = f.read()
def data_for_block(n):
# block 0 is header information, so actual data blocks start at 1
return rom_image[(n-1)*BLOCK_SIZE : n*BLOCK_SIZE]
# suppose 102 blocks
# 100: hash(hash(<00000> + data102) + data101) + data100
# 101: hash(<00000> + data102) + data101
# 102: <00000> + data102
def sha256sum(bytes):
return HASHER(bytes, encoder=RawEncoder)
def hash_for_block(n):
if (n-1)*BLOCK_SIZE < len(rom_image):
data = linked_block(n)
return sha256sum(data)
else:
return b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
def linked_block(n):
if n==0:
return hash_for_block(1) + struct.pack(">L", len(rom_image))
else:
return hash_for_block(n+1) + data_for_block(n)
sig = signing_key.sign(linked_block(0), encoder=RawEncoder)
sock.send(b"ROM0" + sig.signature)
def hexy(h):
return "".join("{:02x} ".format(x) for x in bytearray(h))
def ddec(h):
return "".join("{:02d} ".format(x) for x in bytearray(h))
# header block 0 plus n full blocks plus partial block at end
num_blocks = 2 + len(rom_image)//BLOCK_SIZE
print(f"{num_blocks} blocks to send")
for i in range(0, num_blocks):
h = hash_for_block(i)
print(f"block {i}")
sock.send(linked_block(i))
# Read a line from the socket (until newline)
response = b""
while not response.endswith(b"\n"):
chunk = sock.recv(1)
if not chunk:
break
response += chunk
print(response.decode(errors="replace"))
sock.close()