src/apps/fido_u2f: implement u2f counter

This commit is contained in:
Pavol Rusnak 2018-02-28 18:53:52 +01:00
parent 67d835fd3e
commit c0a0630cba
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
4 changed files with 48 additions and 10 deletions

View File

@ -16,6 +16,7 @@ _USE_PASSPHRASE = const(0x05) # 0x01 or empty
_HOMESCREEN = const(0x06) # bytes
_NEEDS_BACKUP = const(0x07) # 0x01 or empty
_FLAGS = const(0x08) # int
_U2F_COUNTER = const(0x09) # int
def get_device_id() -> str:
@ -96,6 +97,20 @@ def set_flags(flags: int) -> None:
config.set(_APP, _FLAGS, flags.to_bytes(4, 'big'))
def next_u2f_counter() -> int:
b = config.get(_APP, _U2F_COUNTER)
if b is None:
b = 0
else:
b = int.from_bytes(b, 'big') + 1
set_u2f_counter(b)
return b
def set_u2f_counter(cntr: int):
config.set(_APP, _FLAGS, cntr.to_bytes(4, 'big'))
def wipe():
config.wipe()
cache.clear()

View File

@ -15,6 +15,8 @@ from trezor.crypto import hashlib
from trezor.crypto import hmac
from trezor.crypto import random
from trezor.crypto.curve import nist256p1
from apps.common import storage
_HID_RPT_SIZE = const(64)
_CID_BROADCAST = const(0xffffffff) # broadcast channel id
@ -668,20 +670,12 @@ def msg_authenticate_genkey(app_id: bytes, keyhandle: bytes):
return node
# TODO: persistent counter
_authenticate_ctr = 0
def msg_authenticate_sign(challenge: bytes, app_id: bytes, privkey: bytes) -> bytes:
global _authenticate_ctr
flags = bytes([_AUTH_FLAG_TUP])
# get next counter
ctr = _authenticate_ctr
ctr = storage.next_u2f_counter()
ctrbuf = ustruct.pack('>L', ctr)
_authenticate_ctr += 1
# hash input data together with counter
dig = hashlib.sha256()

View File

@ -1,7 +1,7 @@
from trezor.wire import register, protobuf_workflow
from trezor.utils import unimport
from trezor.messages.wire_types import \
LoadDevice, ResetDevice, BackupDevice, WipeDevice, RecoveryDevice, ApplySettings, ApplyFlags, ChangePin
LoadDevice, ResetDevice, BackupDevice, WipeDevice, RecoveryDevice, ApplySettings, ApplyFlags, ChangePin, SetU2FCounter
@unimport
@ -52,6 +52,12 @@ def dispatch_ChangePin(*args, **kwargs):
return change_pin(*args, **kwargs)
@unimport
def dispatch_SetU2FCounter(*args, **kwargs):
from .set_u2f_counter import set_u2f_counter
return set_u2f_counter(*args, **kwargs)
def boot():
# only enable LoadDevice in debug builds
if __debug__:
@ -63,3 +69,4 @@ def boot():
register(ApplySettings, protobuf_workflow, dispatch_ApplySettings)
register(ApplyFlags, protobuf_workflow, dispatch_ApplyFlags)
register(ChangePin, protobuf_workflow, dispatch_ChangePin)
register(SetU2FCounter, protobuf_workflow, dispatch_SetU2FCounter)

View File

@ -0,0 +1,22 @@
from trezor import ui, wire
from trezor.messages import ButtonRequestType, FailureType
from trezor.messages.Success import Success
from trezor.ui.text import Text
from apps.common import storage
from apps.common.confirm import require_confirm
async def set_u2f_counter(ctx, msg):
if msg.u2f_counter is None:
raise wire.FailureError(FailureType.ProcessError, 'No value provided provided')
await require_confirm(ctx, Text(
'Set U2F counter', ui.ICON_CONFIG,
'Do you really want to',
'set the U2F counter',
ui.BOLD, 'to %d?' % msg.u2f_counter),
code=ButtonRequestType.ProtectCall)
storage.set_u2f_counter(msg.u2f_counter)
return Success(message='U2F counter set')