152 lines
3.6 KiB
Python
152 lines
3.6 KiB
Python
#
|
|
# Replacement for modckcc.c and complexity of the bootloader.
|
|
#
|
|
# REMINDER: you must recompile coldcard-mpy if you change this file!
|
|
#
|
|
import ustruct
|
|
#from ubinascii import hexlify as b2a_hex
|
|
#from ubinascii import unhexlify as a2b_hex
|
|
#import utime as time
|
|
|
|
from uerrno import *
|
|
ERANGE = const(34)
|
|
|
|
rng_fd = open('/dev/urandom', 'rb')
|
|
|
|
# Emulate the red/green LED
|
|
import sys
|
|
global genuine_led
|
|
try:
|
|
led_pipe = open(int(sys.argv[3]), 'wb')
|
|
led_pipe.write(b'\x01')
|
|
except:
|
|
pass
|
|
genuine_led = True
|
|
|
|
if 1:
|
|
# remove pauses that lengthen test case times...
|
|
async def no_drama(msg, seconds):
|
|
print("Pause (%ds): %s" % (seconds, msg))
|
|
import ux
|
|
ux.ux_dramatic_pause = no_drama
|
|
|
|
# HACK: reduce size of heap in Unix simulator to be more similar to
|
|
# actual hardware, so we can enjoy those out-of-memory errors too!
|
|
# target, post boot: 25376 bytes
|
|
# - not entirely fair because our pointers may be 64bit
|
|
# - heap for unix port defined (in unix/main.c) to be 1M * ptr size bytes
|
|
# - arm version seems to be able to handle much lower heap size??
|
|
# - unix is not freezing the main code, so those bytecodes take major memory
|
|
#balloon = bytearray(700*1024)
|
|
|
|
|
|
# patch in monitoring of text on screen
|
|
if 1:
|
|
import sim_display
|
|
|
|
|
|
### remainder should be module functions from real ckcc ###
|
|
|
|
def rng():
|
|
# return 30 bit random number
|
|
return ustruct.unpack('I', rng_fd.read(4))[0] >> 2
|
|
|
|
def rng_bytes(buf):
|
|
# Fill a buffer with random bits; caller must provide sized buffer
|
|
actual = rng_fd.readinto(buf)
|
|
assert actual == len(buf)
|
|
|
|
def pin_prefix(pin, buf_out):
|
|
# return 4 bytes (32-bit number)
|
|
# real thing is nothing like this!
|
|
from uhashlib import sha256
|
|
|
|
buf_out[0:4] = sha256(pin).digest()[0:4]
|
|
|
|
return 0
|
|
|
|
def gate(method, buf_io, arg2):
|
|
# the "callgate" into the bootloader
|
|
|
|
# - only spuratically implemented (say it like in _Clueless_)
|
|
# - none of the error checking is repeated here
|
|
# - not trying too hard to fake the hardware-related features
|
|
|
|
if method == 0:
|
|
# version string
|
|
hc = b'1.0.0 time=20180220.092345 git=master@f8d1758'
|
|
buf_io[0:len(hc)] = hc
|
|
return len(hc)
|
|
|
|
if method == 16:
|
|
if len(buf_io) < 8: return ERANGE
|
|
return pin_prefix(buf_io[0:arg2], buf_io)
|
|
|
|
if method == 18:
|
|
from sim_secel import pin_stuff
|
|
return pin_stuff(arg2, buf_io)
|
|
|
|
if method == 4:
|
|
# control the green/red light
|
|
global genuine_led
|
|
if arg2 == 1:
|
|
# clear it
|
|
genuine_led = False
|
|
led_pipe.write(b'\x00')
|
|
return 1 if genuine_led else 0
|
|
|
|
if method == 5:
|
|
# are we a brick? No.
|
|
return 0
|
|
|
|
if method == 19:
|
|
# bag number
|
|
if arg2 == 0:
|
|
buf_io[0:32] = b'CSIM0000' + b'\0'*(32-8)
|
|
if arg2 == 1:
|
|
# not supported: write
|
|
return buf_io
|
|
|
|
if method == 21:
|
|
# high water mark
|
|
if arg2 == 0:
|
|
buf_io[0:8] = b'\x18\x07\x11\x19S\x08\x00\x00'
|
|
return 0
|
|
|
|
return ENOENT
|
|
|
|
def oneway(method, arg2):
|
|
|
|
print("\n\nNOTE: One-way callgate into bootloader: method=%d arg2=%d\n\n" % (method, arg2))
|
|
raise SystemExit
|
|
|
|
def is_simulator():
|
|
return True
|
|
|
|
|
|
def get_sim_root_dirs():
|
|
# return a single path and list of files to pretend to find there
|
|
import ffilib, os
|
|
libc = ffilib.libc()
|
|
|
|
b = bytearray(500)
|
|
cwd = libc.func("s", "getcwd", "pi")(b, len(b))
|
|
assert cwd
|
|
|
|
return cwd, cwd+'/MicroSD'
|
|
|
|
def presume_green():
|
|
global genuine_led
|
|
assert genuine_led == True
|
|
|
|
def breakpoint():
|
|
raise SystemExit
|
|
|
|
def watchpoint():
|
|
pass
|
|
|
|
def vcp_enabled(_):
|
|
return True
|
|
|
|
# EOF
|