feat(core): Support 50 digit PIN and wipe code.

pull/1546/head
Andrew Kozlik 4 years ago committed by Andrew Kozlik
parent c68e91c12a
commit 3084d1196d

@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Allow decreasing the output value in RBF transactions. [#1491]
- Cardano: Allow stake pool registrations with zero margin. [#1502]
- Cardano: Assets are now shown as CIP-0014. [#1510]
- Support PIN of unlimited length. [#1167]
### Deprecated
@ -358,6 +359,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
[#1139]: https://github.com/trezor/trezor-firmware/issues/1139
[#1159]: https://github.com/trezor/trezor-firmware/issues/1159
[#1165]: https://github.com/trezor/trezor-firmware/pull/1165
[#1167]: https://github.com/trezor/trezor-firmware/issues/1167
[#1173]: https://github.com/trezor/trezor-firmware/pull/1173
[#1184]: https://github.com/trezor/trezor-firmware/issues/1184
[#1188]: https://github.com/trezor/trezor-firmware/issues/1188

@ -66,13 +66,15 @@ STATIC mp_obj_t mod_trezorconfig_init(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_init_obj, 0, 1,
mod_trezorconfig_init);
/// def unlock(pin: int, ext_salt: Optional[bytes]) -> bool:
/// def unlock(pin: str, ext_salt: Optional[bytes]) -> bool:
/// """
/// Attempts to unlock the storage with the given PIN and external salt.
/// Returns True on success, False on failure.
/// """
STATIC mp_obj_t mod_trezorconfig_unlock(mp_obj_t pin, mp_obj_t ext_salt) {
uint32_t pin_i = trezor_obj_get_uint(pin);
mp_buffer_info_t pin_b = {0};
mp_get_buffer_raise(pin, &pin_b, MP_BUFFER_READ);
mp_buffer_info_t ext_salt_b = {0};
ext_salt_b.buf = NULL;
if (ext_salt != mp_const_none) {
@ -81,7 +83,7 @@ STATIC mp_obj_t mod_trezorconfig_unlock(mp_obj_t pin, mp_obj_t ext_salt) {
mp_raise_msg(&mp_type_ValueError, "Invalid length of external salt.");
}
if (sectrue != storage_unlock(pin_i, ext_salt_b.buf)) {
if (sectrue != storage_unlock(pin_b.buf, pin_b.len, ext_salt_b.buf)) {
return mp_const_false;
}
return mp_const_true;
@ -89,7 +91,7 @@ STATIC mp_obj_t mod_trezorconfig_unlock(mp_obj_t pin, mp_obj_t ext_salt) {
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorconfig_unlock_obj,
mod_trezorconfig_unlock);
/// def check_pin(pin: int, ext_salt: Optional[bytes]) -> bool:
/// def check_pin(pin: str, ext_salt: Optional[bytes]) -> bool:
/// """
/// Check the given PIN with the given external salt.
/// Returns True on success, False on failure.
@ -148,8 +150,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_get_pin_rem_obj,
mod_trezorconfig_get_pin_rem);
/// def change_pin(
/// oldpin: int,
/// newpin: int,
/// oldpin: str,
/// newpin: str,
/// old_ext_salt: Optional[bytes],
/// new_ext_salt: Optional[bytes],
/// ) -> bool:
@ -158,8 +160,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_get_pin_rem_obj,
/// """
STATIC mp_obj_t mod_trezorconfig_change_pin(size_t n_args,
const mp_obj_t *args) {
uint32_t oldpin = trezor_obj_get_uint(args[0]);
uint32_t newpin = trezor_obj_get_uint(args[1]);
mp_buffer_info_t oldpin = {0};
mp_get_buffer_raise(args[0], &oldpin, MP_BUFFER_READ);
mp_buffer_info_t newpin = {0};
mp_get_buffer_raise(args[1], &newpin, MP_BUFFER_READ);
mp_buffer_info_t ext_salt_b = {0};
const uint8_t *old_ext_salt = NULL;
if (args[2] != mp_const_none) {
@ -176,8 +182,8 @@ STATIC mp_obj_t mod_trezorconfig_change_pin(size_t n_args,
new_ext_salt = ext_salt_b.buf;
}
if (sectrue !=
storage_change_pin(oldpin, newpin, old_ext_salt, new_ext_salt)) {
if (sectrue != storage_change_pin(oldpin.buf, oldpin.len, newpin.buf,
newpin.len, old_ext_salt, new_ext_salt)) {
return mp_const_false;
}
return mp_const_true;
@ -185,13 +191,14 @@ STATIC mp_obj_t mod_trezorconfig_change_pin(size_t n_args,
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorconfig_change_pin_obj, 4,
4, mod_trezorconfig_change_pin);
/// def ensure_not_wipe_code(pin: int) -> None:
/// def ensure_not_wipe_code(pin: str) -> None:
/// """
/// Wipes the device if the entered PIN is the wipe code.
/// """
STATIC mp_obj_t mod_trezorconfig_ensure_not_wipe_code(mp_obj_t pin) {
uint32_t pin_i = trezor_obj_get_uint(pin);
storage_ensure_not_wipe_code(pin_i);
mp_buffer_info_t pin_b = {0};
mp_get_buffer_raise(pin, &pin_b, MP_BUFFER_READ);
storage_ensure_not_wipe_code(pin_b.buf, pin_b.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorconfig_ensure_not_wipe_code_obj,
@ -211,17 +218,21 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorconfig_has_wipe_code_obj,
mod_trezorconfig_has_wipe_code);
/// def change_wipe_code(
/// pin: int,
/// pin: str,
/// ext_salt: Optional[bytes],
/// wipe_code: int,
/// wipe_code: str,
/// ) -> bool:
/// """
/// Change wipe code. Returns True on success, False on failure.
/// """
STATIC mp_obj_t mod_trezorconfig_change_wipe_code(size_t n_args,
const mp_obj_t *args) {
uint32_t pin = trezor_obj_get_uint(args[0]);
uint32_t wipe_code = trezor_obj_get_uint(args[2]);
mp_buffer_info_t pin_b = {0};
mp_get_buffer_raise(args[0], &pin_b, MP_BUFFER_READ);
mp_buffer_info_t wipe_code_b = {0};
mp_get_buffer_raise(args[2], &wipe_code_b, MP_BUFFER_READ);
mp_buffer_info_t ext_salt_b = {0};
const uint8_t *ext_salt = NULL;
if (args[1] != mp_const_none) {
@ -231,7 +242,8 @@ STATIC mp_obj_t mod_trezorconfig_change_wipe_code(size_t n_args,
ext_salt = ext_salt_b.buf;
}
if (sectrue != storage_change_wipe_code(pin, ext_salt, wipe_code)) {
if (sectrue != storage_change_wipe_code(pin_b.buf, pin_b.len, ext_salt,
wipe_code_b.buf, wipe_code_b.len)) {
return mp_const_false;
}
return mp_const_true;

@ -39,6 +39,6 @@
/*
* Current storage version.
*/
#define NORCOW_VERSION ((uint32_t)0x00000002)
#define NORCOW_VERSION ((uint32_t)0x00000003)
#endif

@ -12,7 +12,7 @@ def init(
# extmod/modtrezorconfig/modtrezorconfig.c
def unlock(pin: int, ext_salt: Optional[bytes]) -> bool:
def unlock(pin: str, ext_salt: Optional[bytes]) -> bool:
"""
Attempts to unlock the storage with the given PIN and external salt.
Returns True on success, False on failure.
@ -20,7 +20,7 @@ def unlock(pin: int, ext_salt: Optional[bytes]) -> bool:
# extmod/modtrezorconfig/modtrezorconfig.c
def check_pin(pin: int, ext_salt: Optional[bytes]) -> bool:
def check_pin(pin: str, ext_salt: Optional[bytes]) -> bool:
"""
Check the given PIN with the given external salt.
Returns True on success, False on failure.
@ -57,8 +57,8 @@ def get_pin_rem() -> int:
# extmod/modtrezorconfig/modtrezorconfig.c
def change_pin(
oldpin: int,
newpin: int,
oldpin: str,
newpin: str,
old_ext_salt: Optional[bytes],
new_ext_salt: Optional[bytes],
) -> bool:
@ -68,7 +68,7 @@ def change_pin(
# extmod/modtrezorconfig/modtrezorconfig.c
def ensure_not_wipe_code(pin: int) -> None:
def ensure_not_wipe_code(pin: str) -> None:
"""
Wipes the device if the entered PIN is the wipe code.
"""
@ -83,9 +83,9 @@ def has_wipe_code() -> bool:
# extmod/modtrezorconfig/modtrezorconfig.c
def change_wipe_code(
pin: int,
pin: str,
ext_salt: Optional[bytes],
wipe_code: int,
wipe_code: str,
) -> bool:
"""
Change wipe code. Returns True on success, False on failure.

@ -3,7 +3,6 @@ import utime
import storage.sd_salt
from trezor import config, ui, wire
from trezor.messages import ButtonRequestType
from trezor.pin import pin_to_int
from trezor.ui.components.tt.pin import CANCELLED, PinDialog
from trezor.ui.components.tt.text import Text
from trezor.ui.popup import Popup
@ -71,7 +70,7 @@ async def request_pin_and_sd_salt(
) -> Tuple[str, Optional[bytearray]]:
if config.has_pin():
pin = await request_pin(ctx, prompt, config.get_pin_rem(), allow_cancel)
config.ensure_not_wipe_code(pin_to_int(pin))
config.ensure_not_wipe_code(pin)
else:
pin = ""
@ -98,7 +97,7 @@ async def verify_user_pin(
if config.has_pin():
pin = await request_pin(ctx, prompt, config.get_pin_rem(), allow_cancel)
config.ensure_not_wipe_code(pin_to_int(pin))
config.ensure_not_wipe_code(pin)
else:
pin = ""
@ -106,7 +105,7 @@ async def verify_user_pin(
salt = await request_sd_salt(ctx)
except SdCardUnavailable:
raise wire.PinCancelled("SD salt is unavailable")
if config.unlock(pin_to_int(pin), salt):
if config.unlock(pin, salt):
_last_successful_unlock = utime.ticks_ms()
return
elif not config.has_pin():
@ -116,7 +115,7 @@ async def verify_user_pin(
pin = await request_pin(
ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel
)
if config.unlock(pin_to_int(pin), salt):
if config.unlock(pin, salt):
_last_successful_unlock = utime.ticks_ms()
return

@ -4,7 +4,6 @@ from trezor import config, wire
from trezor.crypto import bip39, slip39
from trezor.messages import BackupType
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.layouts import confirm_action, require
from apps.management import backup_types
@ -46,7 +45,7 @@ async def load_device(ctx, msg):
storage.device.set_passphrase_enabled(msg.passphrase_protection)
storage.device.set_label(msg.label or "")
if msg.pin:
config.change_pin(pin_to_int(""), pin_to_int(msg.pin), None, None)
config.change_pin("", msg.pin, None, None)
return Success(message="Device loaded")

@ -1,7 +1,6 @@
from storage.device import is_initialized
from trezor import config, ui, wire
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.components.tt.text import Text
from trezor.ui.layouts import require, show_success
@ -29,7 +28,7 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success:
# if changing pin, pre-check the entered pin before getting new pin
if curpin and not msg.remove:
if not config.check_pin(pin_to_int(curpin), salt):
if not config.check_pin(curpin, salt):
await error_pin_invalid(ctx)
# get new pin
@ -39,7 +38,7 @@ async def change_pin(ctx: wire.Context, msg: ChangePin) -> Success:
newpin = ""
# write into storage
if not config.change_pin(pin_to_int(curpin), pin_to_int(newpin), salt, salt):
if not config.change_pin(curpin, newpin, salt, salt):
if newpin:
await error_pin_matches_wipe_code(ctx)
else:

@ -1,7 +1,6 @@
from storage.device import is_initialized
from trezor import config, ui, wire
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.components.tt.text import Text
from trezor.ui.layouts import require, show_success
from trezor.ui.popup import Popup
@ -30,7 +29,7 @@ async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success:
if not msg.remove:
# Pre-check the entered PIN.
if config.has_pin() and not config.check_pin(pin_to_int(pin), salt):
if config.has_pin() and not config.check_pin(pin, salt):
await error_pin_invalid(ctx)
# Get new wipe code.
@ -39,7 +38,7 @@ async def change_wipe_code(ctx: wire.Context, msg: ChangeWipeCode) -> Success:
wipe_code = ""
# Write into storage.
if not config.change_wipe_code(pin_to_int(pin), salt, pin_to_int(wipe_code)):
if not config.change_wipe_code(pin, salt, wipe_code):
await error_pin_invalid(ctx)
if wipe_code:

@ -4,7 +4,6 @@ import storage.recovery
from trezor import config, ui, wire, workflow
from trezor.messages import ButtonRequestType
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.components.tt.text import Text
from apps.common.confirm import require_confirm
@ -47,14 +46,14 @@ async def recovery_device(ctx: wire.Context, msg: RecoveryDevice) -> Success:
# for dry run pin needs to be entered
if msg.dry_run:
curpin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN")
if not config.check_pin(pin_to_int(curpin), salt):
if not config.check_pin(curpin, salt):
await error_pin_invalid(ctx)
if not msg.dry_run:
# set up pin if requested
if msg.pin_protection:
newpin = await request_pin_confirm(ctx, allow_cancel=False)
config.change_pin(pin_to_int(""), pin_to_int(newpin), None, None)
config.change_pin("", newpin, None, None)
storage.device.set_passphrase_enabled(bool(msg.passphrase_protection))
if msg.u2f_counter is not None:

@ -6,7 +6,6 @@ from trezor.messages import BackupType
from trezor.messages.EntropyAck import EntropyAck
from trezor.messages.EntropyRequest import EntropyRequest
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.layouts import confirm_backup, confirm_reset_device, require
from trezor.ui.loader import LoadingAnimation
@ -43,7 +42,7 @@ async def reset_device(ctx: wire.Context, msg: ResetDevice) -> Success:
# request and set new PIN
if msg.pin_protection:
newpin = await request_pin_confirm(ctx)
if not config.change_pin(pin_to_int(""), pin_to_int(newpin), None, None):
if not config.change_pin("", newpin, None, None):
raise wire.ProcessError("Failed to set PIN")
# generate and display internal entropy

@ -4,7 +4,6 @@ from trezor import config, ui, wire
from trezor.crypto import random
from trezor.messages import SdProtectOperationType
from trezor.messages.Success import Success
from trezor.pin import pin_to_int
from trezor.ui.components.tt.text import Text
from trezor.ui.layouts import require, show_success
@ -66,9 +65,9 @@ async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success:
# Get the current PIN.
if config.has_pin():
pin = pin_to_int(await request_pin(ctx, "Enter PIN", config.get_pin_rem()))
pin = await request_pin(ctx, "Enter PIN", config.get_pin_rem())
else:
pin = pin_to_int("")
pin = ""
# Check PIN and prepare salt file.
salt, salt_auth_key, salt_tag = _make_salt()
@ -107,7 +106,7 @@ async def sd_protect_disable(ctx: wire.Context, msg: SdProtect) -> Success:
pin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN")
# Check PIN and remove salt.
if not config.change_pin(pin_to_int(pin), pin_to_int(pin), salt, None):
if not config.change_pin(pin, pin, salt, None):
await error_pin_invalid(ctx)
storage.device.set_sd_salt_auth_key(None)
@ -144,7 +143,7 @@ async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success:
new_salt, new_auth_key, new_salt_tag = _make_salt()
await _set_salt(ctx, new_salt, new_salt_tag, stage=True)
if not config.change_pin(pin_to_int(pin), pin_to_int(pin), old_salt, new_salt):
if not config.change_pin(pin, pin, old_salt, new_salt):
await error_pin_invalid(ctx)
storage.device.set_sd_salt_auth_key(new_auth_key)

@ -4,10 +4,6 @@ if False:
from typing import Any, Optional
def pin_to_int(pin: str) -> int:
return int("1" + pin)
_previous_progress: Optional[int] = None
_previous_seconds: Optional[int] = None
keepalive_callback: Any = None

@ -41,16 +41,40 @@ class PinInput(ui.Component):
self.repaint = False
def render_pin(self) -> None:
display.bar(0, 0, ui.WIDTH, 50, ui.BG)
count = len(self.pin)
MAX_LENGTH = const(14) # maximum length of displayed PIN
CONTD_MARK = "<"
BOX_WIDTH = const(240)
DOT_SIZE = const(10)
PADDING = const(14)
PADDING = const(4)
RENDER_Y = const(20)
render_x = (BOX_WIDTH - count * PADDING) // 2
TWITCH = const(3)
display.bar(0, 0, ui.WIDTH, 50, ui.BG)
if len(self.pin) > MAX_LENGTH:
contd_width = display.text_width(CONTD_MARK, ui.BOLD) + PADDING
twitch = TWITCH * (len(self.pin) % 2)
else:
contd_width = 0
twitch = 0
count = min(len(self.pin), MAX_LENGTH)
render_x = (BOX_WIDTH - count * (DOT_SIZE + PADDING) - contd_width) // 2
if contd_width:
display.text(
render_x, RENDER_Y + DOT_SIZE, CONTD_MARK, ui.BOLD, ui.GREY, ui.BG
)
for i in range(0, count):
display.bar_radius(
render_x + i * PADDING, RENDER_Y, DOT_SIZE, DOT_SIZE, ui.GREY, ui.BG, 4
render_x + contd_width + twitch + i * (DOT_SIZE + PADDING),
RENDER_Y,
DOT_SIZE,
DOT_SIZE,
ui.GREY,
ui.BG,
4,
)
def render_prompt(self) -> None:
@ -82,7 +106,7 @@ class PinDialog(ui.Layout):
prompt: str,
subprompt: Optional[str],
allow_cancel: bool = True,
maxlength: int = 9,
maxlength: int = 50,
) -> None:
self.maxlength = maxlength
self.input = PinInput(prompt, subprompt, "")

@ -1,5 +1,4 @@
from common import *
from trezor.pin import pin_to_int
from trezor import config
from storage import device

@ -1,7 +1,6 @@
from common import *
from trezor.crypto import random
from trezor.pin import pin_to_int
from trezor import config
@ -27,7 +26,7 @@ class TestConfig(unittest.TestCase):
def test_wipe(self):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
self.assertEqual(config.unlock('', None), True)
config.set(1, 1, b'hello')
config.set(1, 2, b'world')
v0 = config.get(1, 1)
@ -44,7 +43,7 @@ class TestConfig(unittest.TestCase):
for _ in range(128):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
self.assertEqual(config.unlock('', None), True)
appid, key = random_entry()
value = random.bytes(16)
config.set(appid, key, value)
@ -58,7 +57,7 @@ class TestConfig(unittest.TestCase):
def test_public(self):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
self.assertEqual(config.unlock('', None), True)
appid, key = random_entry()
@ -84,20 +83,46 @@ class TestConfig(unittest.TestCase):
def test_change_pin(self):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
with self.assertRaises(RuntimeError):
config.set(PINAPP, PINKEY, b'value')
self.assertEqual(config.change_pin(pin_to_int('000'), pin_to_int('666'), None, None), False)
self.assertEqual(config.change_pin(pin_to_int(''), pin_to_int('000'), None, None), True)
self.assertEqual(config.get(PINAPP, PINKEY), None)
self.assertTrue(config.unlock('', None))
config.set(1, 1, b'value')
config.init()
self.assertEqual(config.unlock(pin_to_int('000'), None), True)
config.change_pin(pin_to_int('000'), pin_to_int(''), None, None)
config.init()
self.assertEqual(config.unlock(pin_to_int('000'), None), False)
self.assertEqual(config.unlock(pin_to_int(''), None), True)
self.assertEqual(config.get(1, 1), b'value')
PINS = ('123', '123', 'Trezor T', '3141592653589793238462643383279502884197', '')
old_pin = ''
for new_pin in PINS:
self.assertTrue(config.unlock(old_pin, None))
# The APP namespace which is reserved for storage related values is inaccessible even
# when unlocked.
with self.assertRaises(RuntimeError):
config.set(PINAPP, PINKEY, b'value')
self.assertTrue(config.change_pin(old_pin, new_pin, None, None))
# Old PIN cannot be used to change the current PIN.
if old_pin != new_pin:
self.assertFalse(config.change_pin(old_pin, '666', None, None))
# Storage remains unlocked.
self.assertEqual(config.get(1, 1), b'value')
# The APP namespace which is reserved for storage related values is inaccessible even
# when unlocked.
self.assertEqual(config.get(PINAPP, PINKEY), None)
# Old PIN cannot be used to unlock storage.
if old_pin != new_pin:
config.init()
self.assertFalse(config.unlock(old_pin, None))
self.assertEqual(config.get(1, 1), None)
with self.assertRaises(RuntimeError):
config.set(1, 1, b'new value')
# New PIN unlocks the storage.
self.assertTrue(config.unlock(new_pin, None))
self.assertEqual(config.get(1, 1), b'value')
# Lock the storage.
config.init()
old_pin = new_pin
def test_change_sd_salt(self):
salt1 = b"0123456789abcdef0123456789abcdef"
@ -106,37 +131,37 @@ class TestConfig(unittest.TestCase):
# Enable PIN and SD salt.
config.init()
config.wipe()
self.assertTrue(config.unlock(pin_to_int(''), None))
self.assertTrue(config.unlock('', None))
config.set(1, 1, b'value')
self.assertFalse(config.change_pin(pin_to_int(''), pin_to_int(''), salt1, None))
self.assertTrue(config.change_pin(pin_to_int(''), pin_to_int('000'), None, salt1))
self.assertFalse(config.change_pin('', '', salt1, None))
self.assertTrue(config.change_pin('', '000', None, salt1))
self.assertEqual(config.get(1, 1), b'value')
# Disable PIN and change SD salt.
config.init()
self.assertFalse(config.unlock(pin_to_int('000'), None))
self.assertFalse(config.unlock('000', None))
self.assertIsNone(config.get(1, 1))
self.assertTrue(config.unlock(pin_to_int('000'), salt1))
self.assertTrue(config.change_pin(pin_to_int('000'), pin_to_int(''), salt1, salt2))
self.assertTrue(config.unlock('000', salt1))
self.assertTrue(config.change_pin('000', '', salt1, salt2))
self.assertEqual(config.get(1, 1), b'value')
# Disable SD salt.
config.init()
self.assertFalse(config.unlock(pin_to_int('000'), salt2))
self.assertFalse(config.unlock('000', salt2))
self.assertIsNone(config.get(1, 1))
self.assertTrue(config.unlock(pin_to_int(''), salt2))
self.assertTrue(config.change_pin(pin_to_int(''), pin_to_int(''), salt2, None))
self.assertTrue(config.unlock('', salt2))
self.assertTrue(config.change_pin('', '', salt2, None))
self.assertEqual(config.get(1, 1), b'value')
# Check that PIN and SD salt are disabled.
config.init()
self.assertTrue(config.unlock(pin_to_int(''), None))
self.assertTrue(config.unlock('', None))
self.assertEqual(config.get(1, 1), b'value')
def test_set_get(self):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
self.assertEqual(config.unlock('', None), True)
for _ in range(32):
appid, key = random_entry()
value = random.bytes(128)
@ -147,7 +172,7 @@ class TestConfig(unittest.TestCase):
def test_compact(self):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
self.assertEqual(config.unlock('', None), True)
appid, key = 1, 1
for _ in range(259):
value = random.bytes(259)
@ -158,7 +183,7 @@ class TestConfig(unittest.TestCase):
def test_get_default(self):
config.init()
config.wipe()
self.assertEqual(config.unlock(pin_to_int(''), None), True)
self.assertEqual(config.unlock('', None), True)
for _ in range(128):
appid, key = random_entry()
value = config.get(appid, key)

Loading…
Cancel
Save