import ctypes as c import os sectrue = -1431655766 # 0xAAAAAAAAA fname = os.path.join(os.path.dirname(__file__), "libtrezor-storage0.so") class Storage: def __init__(self) -> None: self.lib = c.cdll.LoadLibrary(fname) self.flash_size = c.cast(self.lib.FLASH_SIZE, c.POINTER(c.c_uint32))[0] self.flash_buffer = c.create_string_buffer(self.flash_size) c.cast(self.lib.FLASH_BUFFER, c.POINTER(c.c_void_p))[0] = c.addressof( self.flash_buffer ) def init(self) -> None: self.lib.storage_init(0) def wipe(self) -> None: self.lib.storage_wipe() def check_pin(self, pin: str) -> bool: return sectrue == self.lib.storage_check_pin(c.c_uint32(int("1" + pin))) def unlock(self, pin: str) -> bool: return sectrue == self.lib.storage_unlock(c.c_uint32(int("1" + pin))) def has_pin(self) -> bool: return sectrue == self.lib.storage_has_pin() def change_pin(self, oldpin: str, newpin: str) -> bool: return sectrue == self.lib.storage_change_pin( c.c_uint32(int("1" + oldpin)), c.c_uint32(int("1" + newpin)) ) def get(self, key: int) -> bytes: val_ptr = c.c_void_p() val_len = c.c_uint16() if sectrue != self.lib.storage_get( c.c_uint16(key), c.byref(val_ptr), c.byref(val_len) ): raise RuntimeError("Failed to find key in storage.") return c.string_at(val_ptr, size=val_len.value) def set(self, key: int, val: bytes) -> None: if sectrue != self.lib.storage_set(c.c_uint16(key), val, c.c_uint16(len(val))): raise RuntimeError("Failed to set value in storage.") def _dump(self) -> bytes: # return just sectors 4 and 16 of the whole flash return [ self.flash_buffer[0x010000 : 0x010000 + 0x10000], self.flash_buffer[0x110000 : 0x110000 + 0x10000], ] def _get_flash_buffer(self) -> bytes: return bytes(self.flash_buffer) def _set_flash_buffer(self, buf: bytes) -> None: if len(buf) != self.flash_size: raise RuntimeError("Failed to set flash buffer due to length mismatch.") self.flash_buffer = buf