def verify_pack_dfu(keys, filename): """Verify packed dfu file against keys. Gathers decrypted binary data.""" full_sig = pyhy.hydro_sign(MBOOT_PACK_HYDRO_CONTEXT) _, elems = dfu_read(filename) base_addr = None binary_data = b"" for addr, data in elems: if base_addr is None: base_addr = addr header = struct.unpack("<BBBBII", data[:12]) chunk = data[12:12 + header[5]] sig = data[12 + header[5]:] sig_pass = pyhy.hydro_sign_verify(sig, data[:12] + chunk, MBOOT_PACK_HYDRO_CONTEXT, keys.sign_pk) assert sig_pass if header[1] == MBOOT_PACK_CHUNK_FULL_SIG: actual_sig = chunk[-64:] else: chunk = pyhy.hydro_secretbox_decrypt(chunk, 0, MBOOT_PACK_HYDRO_CONTEXT, keys.secretbox) assert chunk is not None if header[1] == MBOOT_PACK_CHUNK_FW_GZIP: chunk = zlib.decompress(chunk, wbits=-15) full_sig.update(chunk) assert addr == base_addr + len(binary_data) binary_data += chunk full_sig_pass = full_sig.final_verify(actual_sig, keys.sign_pk) assert full_sig_pass return [{"address": base_addr, "data": binary_data}]
def on_msg_server(client, userdata, msg): print('on_msg_server') if userdata['established'] == True: ptxt = pyhy.hydro_secretbox_decrypt(msg.payload, 0, CTX, userdata['session_kp'].rx) if ptxt is not None: print('Rx > %s' % ptxt.decode()) ctxt = pyhy.hydro_secretbox_encrypt( 'You sent: "%s"' % ptxt.decode(), 0, CTX, userdata['session_kp'].tx) client.publish(SERVER_PUB_TOPIC, ctxt) else: userdata['established'] = False userdata['state'] = 0 else: ################################## N ################################### if userdata['type'] == 'n': pkt1 = msg.payload server_kp = get_current_kp(userdata) session_kp_server = pyhy.hydro_kx_n_2(server_kp, pkt1) # pyhy.dump_session_keypair_hex(session_kp_server) userdata['session_kp'] = session_kp_server userdata['established'] = True ################################## KK ################################## elif userdata['type'] == 'kk': pkt1 = msg.payload server_kp = get_current_kp(userdata) session_kp_server, pkt2 = pyhy.hydro_kx_kk_2( pkt1, pyhy.unhexify(userdata['kp']['client-pk']), server_kp) userdata['session_kp'] = session_kp_server userdata['established'] = True publish.single(SERVER_PUB_TOPIC, pkt2, hostname=MQTT_HOST) ################################## XX ################################## elif userdata['type'] == 'xx': if userdata['state'] == 0: pkt1 = msg.payload xx_server = userdata['kx'] # kx client created on init server_kp = get_current_kp(userdata) pkt2 = xx_server.xx_2(pkt1, server_kp) userdata['state'] = 2 publish.single(SERVER_PUB_TOPIC, pkt2, hostname=MQTT_HOST) print('Server (xx) pkt2 sent') elif userdata['state'] == 2: pkt3 = msg.payload xx_server = userdata['kx'] # kx client created on init (session_kp_server, peer_pk_client) = xx_server.xx_4(pkt3) assert session_kp_server is not None userdata['session_kp'] = session_kp_server userdata['state'] = 0 userdata['established'] = True if peer_pk_client is not None: print('Discovered a (client) peer: %s' % peer_pk_client.hex()) print('Server (xx) - Established') else: print('missing/invalid type in userdata') sys.exit(1)
def datagram_received(self, datagram_bytes, addr): session_id, frame = datagram_bytes[0:12], datagram_bytes[12:] print('Received %r from %s' % (session_id, addr)) if session_id == UdpSimpleRpcTransport.DUMMY_SESSION: dec_datagram_bytes = pyhy.hydro_secretbox_decrypt( frame, 0, CTX, self.handler.netkey) data = sign_unpack(dec_datagram_bytes) data['adr'].append("/ip/%s/udp/%d" % addr) self.handler.handleAdvertise(data) else: conn = self.make_connection(addr) self.handler.handleData(session_id, frame, conn)
def on_msg_client(client, userdata, msg): if userdata['established'] == True: ptxt = pyhy.hydro_secretbox_decrypt(msg.payload, 0, CTX, userdata['session_kp'].rx) print('Rx > %s' % ptxt.decode()) else: ################################## KK ################################## if userdata['type'] == 'kk': if userdata['state'] != 1: print('Client state must be 1 to process next pkt') return pkt2 = msg.payload kk_client = userdata['kx'] # kx client created on init session_kp_client = kk_client.kk_3( pkt2, pyhy.unhexify(userdata['kp']['server-pk'])) if session_kp_client is not None: userdata['session_kp'] = session_kp_client userdata['established'] = True print('Client (kk) session established') else: print('WARN: Client (kk) session failed') ################################## XX ################################## elif userdata['type'] == 'xx': if userdata['state'] == 1: pkt2 = msg.payload client_kp = get_current_kp(userdata) xx_client = userdata['kx'] # kx client created on init (session_kp_client, pkt3, peer_pk_server) = xx_client.xx_3(pkt2, client_kp) assert session_kp_client is not None assert pkt3 is not None if peer_pk_server is not None: print('Discovered a (server) peer: %s' % peer_pk_server.hex()) userdata['state'] = 0 userdata['session_kp'] = session_kp_client userdata['established'] = True client.publish(CLIENT_PUB_TOPIC, pkt3) print('Client (xx) pkt3 sent, connection set to established') elif userdata['state'] == 0: print('TODO: restart connection') else: print('Client state invalid') ######################################################## return
def verify_pack_dfu(keys, filename): full_sig = pyhy.hydro_sign(MBOOT_PACK_HYDRO_CONTEXT) _, elems = dfu_read(filename) for addr, data in elems: header = struct.unpack("<BBBBII", data[:12]) chunk = data[12:12 + header[5]] sig = data[12 + header[5]:] sig_pass = pyhy.hydro_sign_verify(sig, data[:12] + chunk, MBOOT_PACK_HYDRO_CONTEXT, keys.sign_pk) assert sig_pass if header[1] == MBOOT_PACK_CHUNK_FULL_SIG: actual_sig = chunk[-64:] else: chunk = pyhy.hydro_secretbox_decrypt(chunk, 0, MBOOT_PACK_HYDRO_CONTEXT, keys.secretbox) assert chunk is not None if header[1] == MBOOT_PACK_CHUNK_FW_GZIP: chunk = zlib.decompress(chunk, wbits=-15) full_sig.update(chunk) full_sig_pass = full_sig.final_verify(actual_sig, keys.sign_pk) assert full_sig_pass
def decrypt(self, enc_frame): return pyhy.hydro_secretbox_decrypt(enc_frame, 0, CTX, self.session_kp.rx)