def start_default(genfunc): global _default global _default_genfunc _default_genfunc = genfunc _default = _default_genfunc() log.info(__name__, 'start default %s', _default) loop.schedule_task(_default)
async def write(session_id, pbuf_msg): log.info(__name__, 'session %x: write(%s)', session_id, pbuf_msg) pbuf_type = pbuf_msg.__class__ msg_data = pbuf_type.dumps(pbuf_msg) msg_type = pbuf_type.MESSAGE_WIRE_TYPE sessions.get_codec(session_id).encode(session_id, msg_type, msg_data, _write_report)
def start(workflow): if _default is not None: close_default() _started.append(workflow) log.info(__name__, 'start %s', workflow) loop.schedule_task(_watch(workflow)) ui.display.backlight(ui.BACKLIGHT_NORMAL)
def start_default(genfunc): global _default global _default_genfunc _default_genfunc = genfunc _default = _default_genfunc() log.info(__name__, 'start default %s', _default) loop.schedule_task(_default) ui.display.backlight(ui.BACKLIGHT_NORMAL)
def listen(session_id, handler, *args): if session_id not in opened: raise KeyError('Session %x is unknown' % session_id) if session_id in readers: raise KeyError('Session %x is already being listened on' % session_id) log.info(__name__, 'session %x: listening', session_id) decoder = get_codec(session_id).decode_stream(session_id, handler, *args) decoder.send(None) readers[session_id] = decoder
def msg_register(req: Msg) -> Cmd: global _state global _lastreq from apps.common import storage if not storage.is_initialized(): log.warning(__name__, 'not initialized') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # check length of input data if len(req.data) != 64: log.warning(__name__, '_SW_WRONG_LENGTH req.data') return msg_error(req.cid, _SW_WRONG_LENGTH) # parse challenge and app_id chal = req.data[:32] app_id = req.data[32:] # check equality with last request if _lastreq is None or _lastreq.__dict__ != req.__dict__: if _state is not None: _state.kill() _state = None _lastreq = req # wait for a button or continue if _state is not None and utime.ticks_ms() > _state.deadline_ms: _state.kill() _state = None if _state is None: _state = ConfirmState(_CONFIRM_REGISTER, app_id) _state.fork() if _state.confirmed is None: log.info(__name__, 'waiting for button') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) _state = None buf = msg_register_sign(chal, app_id) return Cmd(req.cid, _CMD_MSG, buf)
def msg_register(req: Msg, state: ConfirmState) -> Cmd: from apps.common import storage if not storage.is_initialized(): if __debug__: log.warning(__name__, "not initialized") return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # check length of input data if len(req.data) != 64: if __debug__: log.warning(__name__, "_SW_WRONG_LENGTH req.data") return msg_error(req.cid, _SW_WRONG_LENGTH) # parse challenge and app_id chal = req.data[:32] app_id = req.data[32:] # check equality with last request if not state.compare(_CONFIRM_REGISTER, req.data): if not state.setup(_CONFIRM_REGISTER, req.data, app_id): return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) state.keepalive() # wait for a button or continue if not state.confirmed: if __debug__: log.info(__name__, "waiting for button") return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # sign the registration challenge and return if __debug__: log.info(__name__, "signing register") buf = msg_register_sign(chal, app_id) state.reset() return Cmd(req.cid, _CMD_MSG, buf)
def msg_authenticate(req: Msg) -> Cmd: global _state global _lastreq from apps.common import storage if not storage.is_initialized(): log.warning(__name__, 'not initialized') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # we need at least keyHandleLen if len(req.data) <= _REQ_CMD_AUTHENTICATE_KHLEN: log.warning(__name__, '_SW_WRONG_LENGTH req.data') return msg_error(req.cid, _SW_WRONG_LENGTH) # check keyHandleLen khlen = req.data[_REQ_CMD_AUTHENTICATE_KHLEN] if khlen != 64: log.warning(__name__, '_SW_WRONG_LENGTH khlen') return msg_error(req.cid, _SW_WRONG_LENGTH) auth = overlay_struct(req.data, req_cmd_authenticate(khlen)) # check the keyHandle and generate the signing key node = msg_authenticate_genkey(auth.appId, auth.keyHandle) if node is None: # specific error logged in msg_authenticate_genkey return msg_error(req.cid, _SW_WRONG_DATA) # if _AUTH_CHECK_ONLY is requested, return, because keyhandle has been checked already if req.p1 == _AUTH_CHECK_ONLY: log.info(__name__, '_AUTH_CHECK_ONLY') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # from now on, only _AUTH_ENFORCE is supported if req.p1 != _AUTH_ENFORCE: log.info(__name__, '_AUTH_ENFORCE') return msg_error(req.cid, _SW_WRONG_DATA) # check equality with last request if _lastreq is None or _lastreq.__dict__ != req.__dict__: if _state is not None: _state.kill() _state = None _lastreq = req # wait for a button or continue if _state is not None and utime.ticks_ms() > _state.deadline_ms: _state.kill() _state = None if _state is None: _state = ConfirmState(_CONFIRM_AUTHENTICATE, auth.appId) _state.fork() if _state.confirmed is None: log.info(__name__, 'waiting for button') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) _state = None buf = msg_authenticate_sign(auth.chal, auth.appId, node.private_key()) return Cmd(req.cid, _CMD_MSG, buf)
def perf_info(): while True: gc.collect() log.info(__name__, "mem_alloc: %d", gc.mem_alloc()) yield loop.Sleep(1000000)
async def read(session_id, *wire_types): log.info(__name__, 'session %x: read(%s)', session_id, wire_types) signal = loop.Signal() sessions.listen(session_id, _handle_response, wire_types, signal) return await signal
def msg_authenticate(req: Msg, state: ConfirmState) -> Cmd: from apps.common import storage if not storage.is_initialized(): if __debug__: log.warning(__name__, 'not initialized') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # we need at least keyHandleLen if len(req.data) <= _REQ_CMD_AUTHENTICATE_KHLEN: if __debug__: log.warning(__name__, '_SW_WRONG_LENGTH req.data') return msg_error(req.cid, _SW_WRONG_LENGTH) # check keyHandleLen khlen = req.data[_REQ_CMD_AUTHENTICATE_KHLEN] if khlen != 64: if __debug__: log.warning(__name__, '_SW_WRONG_LENGTH khlen') return msg_error(req.cid, _SW_WRONG_LENGTH) auth = overlay_struct(req.data, req_cmd_authenticate(khlen)) # check the keyHandle and generate the signing key node = msg_authenticate_genkey(auth.appId, auth.keyHandle) if node is None: # specific error logged in msg_authenticate_genkey return msg_error(req.cid, _SW_WRONG_DATA) # if _AUTH_CHECK_ONLY is requested, return, because keyhandle has been checked already if req.p1 == _AUTH_CHECK_ONLY: if __debug__: log.info(__name__, '_AUTH_CHECK_ONLY') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # from now on, only _AUTH_ENFORCE is supported if req.p1 != _AUTH_ENFORCE: if __debug__: log.info(__name__, '_AUTH_ENFORCE') return msg_error(req.cid, _SW_WRONG_DATA) # check equality with last request if not state.compare(_CONFIRM_AUTHENTICATE, req.data): if not state.setup(_CONFIRM_AUTHENTICATE, req.data, auth.appId): return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) state.keepalive() # wait for a button or continue if not state.confirmed: if __debug__: log.info(__name__, 'waiting for button') return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # sign the authentication challenge and return if __debug__: log.info(__name__, 'signing authentication') buf = msg_authenticate_sign(auth.chal, auth.appId, node.private_key()) state.reset() return Cmd(req.cid, _CMD_MSG, buf)
def close(session_id): log.info(__name__, 'session %x: close', session_id) opened.discard(session_id) readers.pop(session_id, None)
def _write_report(report): if __debug__: log.info(__name__, 'write report %s', ubinascii.hexlify(report)) msg.send(_interface, report)
def close_default(): global _default log.info(__name__, 'close default %s', _default) _default.close() _default = None
def start(workflow): if _default is not None: close_default() _started.append(workflow) log.info(__name__, 'start %s', workflow) loop.schedule_task(_watch(workflow))
async def diag(ctx, msg, **kwargs) -> Failure: log.debug(__name__, "----diagnostics") gc.collect() if msg.ins == 0: check_mem(0) return retit() elif msg.ins == 1: check_mem(1) micropython.mem_info(1) return retit() elif msg.ins == 2: log.debug(__name__, "_____________________________________________") log.debug(__name__, "_____________________________________________") log.debug(__name__, "_____________________________________________") return retit() elif msg.ins == 3: pass elif msg.ins == 4: total = 0 monero = 0 for k, v in sys.modules.items(): log.info(__name__, "Mod[%s]: %s", k, v) total += 1 if k.startswith("apps.monero"): monero += 1 log.info(__name__, "Total modules: %s, Monero modules: %s", total, monero) return retit() elif msg.ins in [5, 6, 7]: check_mem() from apps.monero.xmr import bulletproof as bp check_mem("BP Imported") from apps.monero.xmr import crypto check_mem("Crypto Imported") bpi = bp.BulletProofBuilder() bpi.gc_fnc = gc.collect bpi.gc_trace = log_trace vals = [crypto.Scalar((1 << 30) - 1 + 16), crypto.Scalar(22222)] masks = [crypto.random_scalar(), crypto.random_scalar()] check_mem("BP pre input") if msg.ins == 5: bp_res = bpi.prove_testnet(vals[0], masks[0]) check_mem("BP post prove") bpi.verify_testnet(bp_res) check_mem("BP post verify") elif msg.ins == 6: bp_res = bpi.prove(vals[0], masks[0]) check_mem("BP post prove") bpi.verify(bp_res) check_mem("BP post verify") elif msg.ins == 7: bp_res = bpi.prove_batch(vals, masks) check_mem("BP post prove") bpi.verify(bp_res) check_mem("BP post verify") return retit() return retit()
def msg_authenticate(req: Msg, state: ConfirmState) -> Cmd: from apps.common import storage if not storage.is_initialized(): if __debug__: log.warning(__name__, "not initialized") return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # we need at least keyHandleLen if len(req.data) <= _REQ_CMD_AUTHENTICATE_KHLEN: if __debug__: log.warning(__name__, "_SW_WRONG_LENGTH req.data") return msg_error(req.cid, _SW_WRONG_LENGTH) # check keyHandleLen khlen = req.data[_REQ_CMD_AUTHENTICATE_KHLEN] if khlen != 64: if __debug__: log.warning(__name__, "_SW_WRONG_LENGTH khlen") return msg_error(req.cid, _SW_WRONG_LENGTH) auth = overlay_struct(req.data, req_cmd_authenticate(khlen)) # check the keyHandle and generate the signing key node = msg_authenticate_genkey(auth.appId, auth.keyHandle, "<8L") if node is None: # prior to firmware version 2.0.8, keypath was serialized in a # big-endian manner, instead of little endian, like in trezor-mcu. # try to parse it as big-endian now and check the HMAC. node = msg_authenticate_genkey(auth.appId, auth.keyHandle, ">8L") if node is None: # specific error logged in msg_authenticate_genkey return msg_error(req.cid, _SW_WRONG_DATA) # if _AUTH_CHECK_ONLY is requested, return, because keyhandle has been checked already if req.p1 == _AUTH_CHECK_ONLY: if __debug__: log.info(__name__, "_AUTH_CHECK_ONLY") return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # from now on, only _AUTH_ENFORCE is supported if req.p1 != _AUTH_ENFORCE: if __debug__: log.info(__name__, "_AUTH_ENFORCE") return msg_error(req.cid, _SW_WRONG_DATA) # check equality with last request if not state.compare(_CONFIRM_AUTHENTICATE, req.data): if not state.setup(_CONFIRM_AUTHENTICATE, req.data, auth.appId): return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) state.keepalive() # wait for a button or continue if not state.confirmed: if __debug__: log.info(__name__, "waiting for button") return msg_error(req.cid, _SW_CONDITIONS_NOT_SATISFIED) # sign the authentication challenge and return if __debug__: log.info(__name__, "signing authentication") buf = msg_authenticate_sign(auth.chal, auth.appId, node.private_key()) state.reset() return Cmd(req.cid, _CMD_MSG, buf)
def open(session_id=None): if session_id is None: session_id = generate() log.info(__name__, 'session %x: open', session_id) opened.add(session_id) return session_id