Пример #1
0
def wipe_flash_filesystem():
    # erase and re-format the flash filesystem (/flash/)
    import ckcc, pyb
    from main import dis, settings

    dis.fullscreen('Erasing...')
    os.umount('/flash')

    # from extmod/vfs.h
    BP_IOCTL_SEC_COUNT = (4)
    BP_IOCTL_SEC_SIZE = (5)

    # block-level erase
    fl = pyb.Flash()
    bsize = fl.ioctl(BP_IOCTL_SEC_SIZE, 0)
    assert bsize == 512
    bcount = fl.ioctl(BP_IOCTL_SEC_COUNT, 0)

    blk = bytearray(bsize)
    ckcc.rng_bytes(blk)

    # trickiness: actual flash blocks are offset by 0x100 (FLASH_PART1_START_BLOCK)
    # so fake MBR can be inserted. Count also inflated by 2X, but not from ioctl above.
    for n in range(bcount):
        fl.writeblocks(n + 0x100, blk)
        ckcc.rng_bytes(blk)

        dis.progress_bar_show(n * 2 / bcount)

    # rebuild and mount /flash
    dis.fullscreen('Rebuilding...')
    ckcc.wipe_fs()

    # re-store settings
    settings.save()
Пример #2
0
async def make_complete_backup(fname_pattern='backup.7z', write_sflash=False):

    # pick a password: like bip39 but no checksum word
    #
    b = bytearray(32)
    while 1:
        ckcc.rng_bytes(b)
        words = tcc.bip39.from_data(b).split(' ')[0:num_pw_words]

        ch = await seed.show_words(words,
                        prompt="Record this (%d word) backup file password:\n", escape='6')

        if ch == '6' and not write_sflash:
            # Secret feature: plaintext mode
            # - only safe for people living in faraday cages inside locked vaults.
            if await ux_confirm("The file will **NOT** be encrypted and "
                                "anyone who finds the file will get all of your money for free!"):
                words = []
                fname_pattern = 'backup.txt'
                break
            continue

        if ch == 'x':
            return

        break


    if words:
        # quiz them, but be nice and do a shorter test.
        ch = await seed.word_quiz(words, limited=(num_pw_words//3))
        if ch == 'x': return

    return await write_complete_backup(words, fname_pattern, write_sflash)
Пример #3
0
def wipe_microsd_card():
    import ckcc, pyb
    from main import dis

    try:
        os.umount('/sd')
    except:
        pass

    sd = pyb.SDCard()
    assert sd

    if not sd.present(): return

    # power cycle so card details (like size) are re-read from current card
    sd.power(0)
    sd.power(1)

    dis.fullscreen('Part Erase...')
    cutoff = 1024  # arbitrary
    blk = bytearray(512)

    for bnum in range(cutoff):
        ckcc.rng_bytes(blk)
        sd.writeblocks(bnum, blk)
        dis.progress_bar_show(bnum / cutoff)

    dis.fullscreen('Formating...')

    # remount, with newfs option
    os.mount(sd, '/sd', readonly=0, mkfs=1)
Пример #4
0
    def pick_secret(cls, auth_mode):
        # always 10 bytes for no reason => 80 bits of entropy
        # return binary secret, and encoded value for new user to see
        import ckcc
        b = bytearray(10)
        ckcc.rng_bytes(b)
        picked = b32encode(b)

        if auth_mode == USER_AUTH_HMAC:
            picked = picked.lower()
            b = calc_hmac_key(picked.encode('ascii'))

        return b, picked
Пример #5
0
async def make_new_wallet():
    # Pick a new random seed, and 

    await ux_dramatic_pause('Generating...', 4)

    # always full 24-word (256 bit) entropy
    seed = bytearray(32)
    rng_bytes(seed)

    assert len(set(seed)) > 4       # TRNG failure

    # hash to mitigate bias in TRNG
    seed = tcc.sha256(seed).digest()

    await approve_word_list(seed)
Пример #6
0
def random_bytes(count):
    assert 8 <= count < 1024
    rv = bytearray(count)
    rng_bytes(rv)
    return rv
Пример #7
0
async def make_new_wallet():
    # pick a new random seed, and force them to
    # write it down, then save it.

    from main import dis
    from uasyncio import sleep_ms

    # CONCERN: memory is really contaminated with secrets in this process, much more so
    # than during normal operation. Maybe we should block USB and force a reboot as well?

    # LESSON LEARNED: if the user is writting down the words, as we have
    # vividly instructed, then it's a big deal to lose those words and have to start
    # over. So confirm that action, and don't volunteer it.

    # dramatic pause
    await ux_dramatic_pause('Generating...', 4)

    # always full 24-word (256 bit) entropy
    seed = bytearray(32)
    rng_bytes(seed)

    assert len(set(seed)) > 4, "impossible luck?"

    # hash to mitigate bias in TRNG
    seed = tcc.sha256(seed).digest()

    words = tcc.bip39.from_data(seed).split(' ')
    assert len(words) == 24

    #print('words: ' + ' '.join(words))

    while 1:
        # show the seed words
        ch = await show_words(words, escape='6')

        if ch == 'x':
            # user abort
            if await ux_confirm("Throw away those words and stop this process?"
                                ):
                return
            else:
                continue

        if ch == '6':
            # wants to skip the quiz (undocumented)
            if await ux_confirm(
                    "Skipping the quiz means you might have "
                    "recorded the seed wrong and will be crying later."):
                break

        # Perform a test, to check they wrote them down
        ch = await word_quiz(words)
        if ch == 'x':
            # user abort quiz
            if await ux_confirm(
                    "Throw away those words and stop this process? Press X to see the word list again and restart the quiz."
            ):
                return

            # show the words again, but don't change them
            continue

        # quiz passed
        break

    # Done!
    set_seed_value(words)

    # send them to home menu, now with a wallet enabled
    goto_top_menu()
Пример #8
0
def urandom(l):
    rv = bytearray(l)
    ckcc.rng_bytes(rv)
    return rv