82 lines
1.9 KiB
Python
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()
|